Lumenco Catalog MCP Server
Lumenco 카탈로그 (Phase 1 스크래퍼 + Phase 2 MCP)
이 저장소는 두 개의 계층으로 구성됩니다:
Phase 1은
https://en.staging.lumenco.ca/를 스크래핑하여 PostgreSQL에 저장합니다.Phase 2는 해당 카탈로그를 읽기 전용 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 스토어프론트입니다.
영역 | 동작 |
Brands |
|
Brand listings |
|
Products | 정규 URL(예: |
Spec sheets | 일반적으로 |
Sitemap |
|
GraphQL |
|
Fetching | 제품 페이지는 서버 렌더링됩니다. Scrapling의 HTTP |
크롤러는 en.staging.lumenco.ca에 머뭅니다. 외부 Specification Sheet PDF는 제품 문서로 다운로드될 수 있습니다. 광고, 분석, 장바구니, 결제, 소셜 URL은 무시됩니다.
robots.txt는 공개 검색 엔진용으로 작성되었습니다(User-agent: *는 /brand 및 일부 CMS 페이지를 제외한 대부분의 경로를 허용하지 않음). 이 스크래퍼는 스테이징에 대한 인가된 카탈로그 수집이므로 ROBOTS_TXT_OBEY는 기본적으로 false입니다. Scrapling이 해당 파일을 존중하도록 하려면 true로 설정하세요.
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.txtScrapling의 HTTP/브라우저 추가 기능은 scrapling[fetchers]를 통해 포함됩니다. 브라우저 폴백(DynamicFetcher)이 필요하면 브라우저 바이너리를 설치하세요:
scrapling install스캔/이미지 전용 사양 PDF를 위한 선택적 OCR:
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은 이미 5432를 사용 중인 Windows PostgreSQL 설치와 충돌을 피함)
환경 구성을 복사하세요:
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를 전달하지 않는 한 건너뜁니다.실패한 제품은 재시도됩니다.
문서 해시가 변경되지 않은 경우 Specification 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(Lumenco의 "Specification Sheet" 컨트롤)동등한 라벨: Specification Sheet, Spec Sheet, Specifications, Technical Data, PDF, Fiche technique 등.
그런 다음 파이프라인은:
문서 URL을 저장합니다.
httpx로 파일을 다운로드합니다(브라우저가 아님).PDF 매직 바이트(
%PDF)를 검증합니다.결정적 복사본을 저장합니다:
data/specifications/{sku}_{hash16}.pdf.PyMuPDF로 텍스트를 추출합니다.
페이지/섹션 구분을 유지하면서 공백을 정리합니다.
추출된 텍스트, SHA-256 해시, 방법, 상태를 저장합니다.
PDF에서
Label: Value줄을 필드를 임의로 만들지 않고 파싱합니다.PDF 사양을 제품 페이지 사양과 병합하고 출처를 보존합니다:
{
"Voltage": {
"value": "120-277V",
"source": "product_page",
"raw": "120-277V",
"normalized": {"min": 120, "max": 277, "unit": "V"}
}
}PDF에 텍스트가 거의 없거나 없으면 상태는 ocr_required입니다(또는 ENABLE_OCR=true일 때 OCR이 시도됩니다). 비어 있는 성공적 추출은 조용히 저장되지 않습니다.
변경되지 않은 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/가격 파싱, 사양 시트 감지, 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개 제품 데이터 품질
이 프로젝트는 현재 통제된 약 100개 제품의 Lumenco 데이터셋을 대상으로 합니다. 라이브 카탈로그에는 30,000개 이상의 SKU가 있으며, 전체 카탈로그 크롤링은 의도적으로 범위에서 제외됩니다.
파이프라인
Scrapling → 제품 추출 → PDF 다운로드 → PDF 텍스트 또는 OCR → 사양 정규화 → PostgreSQL → 읽기 전용 MCP
PDF 텍스트 추출이 먼저 시도됩니다. OCR(pytesseract를 통한 Tesseract)은 PDF에 의미 있는 텍스트가 없을 때만 실행됩니다. ENABLE_OCR=true로 설정하고 Tesseract와 pip install pytesseract Pillow를 설치하세요.
정규화된 사양은 출처와 충돌 플래그를 유지합니다. 원시 사양 시트 텍스트는 specification_documents.extracted_text에 저장됩니다. MCP get_product는 간결한 구조화된 사양을 반환하며, get_product_specifications는 include_raw_text=true일 때 원시 텍스트를 포함할 수 있습니다.
프랑스어 Magento 카테고리 URL(예: /eclairage-interieur 및 /electricite)은 영어 호스트의 공유 헤더에 여전히 나타납니다. 해당 URL은 그곳에서 404를 반환합니다. 크롤러는 해당 경로를 큐에 넣지 않습니다. 또한 새 크롤은 격리된 Scrapling 체크포인트 디렉터리(data/crawl/run-<id>)를 사용하므로 이전 일시 중지 파일이 수천 개의 카테고리 URL을 재개할 수 없습니다. --resume은 공유 data/crawl 체크포인트를 계속할 때만 사용하세요.
영어 호스트로 다시 작성된 프랑스어 Magento 카테고리 URL은 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설정
pgvector가 포함된 Postgres 이미지를 사용하세요(
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
새로운 읽기 전용 도구: search_similar_products. 저장된 벡터만 읽으며 임베딩 API를 호출하거나 Lumenco를 스크래핑하지 않습니다. 기존 추천 도구는 변경되지 않습니다.
Phase 3B — 하이브리드 추천 엔진
추천은 pgvector 유사도와 구조화된 제품 규칙을 결합합니다. 벡터 유사도만으로는 충분하지 않습니다. 18W T8 튜브, 30W T8 튜브, 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(읽기 전용)를 호출합니다.
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 카탈로그(30,000개 이상)는 의도적으로 범위에서 제외.
2단계 — Lumenco 제품 데이터베이스 MCP
Lumenco Product Database라는 이름의 읽기 전용 Streamable HTTP MCP 서버.
아키텍처
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).카탈로그가 채워지도록 크롤링 실행.
requirements.txt에 MCP 추가 기능이 아직 없다면 설치:
pip install -r requirements.txt.env에 MCP 변수 설정:
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전송 방식 Streamable HTTP로 http://localhost:8000/mcp에 연결. MCP_AUTH_TOKEN이 설정된 경우 다음을 추가:
Authorization: Bearer <token>여덟 개 도구가 모두 나열되고 실행 가능한지 확인.
사용 가능한 도구
모든 도구는 PostgreSQL만 읽음. Lumenco URL을 가져오지 않음.
get_catalog_status
카탈로그 크기 및 최신 크롤링 신선도. 입력 없음.
get_listing_products
브랜드/카테고리 목록 URL의 제품을 원래 목록 순서대로 반환.
입력 | 필수 | 참고 |
| 예 | 정규화되어 데이터베이스 키로 사용됨 |
| 아니요 | 기본값 20, 최대 100 |
| 아니요 | 기본값 0 |
get_product
product_id 및/또는 sku로 완전한 제품 레코드 반환.
get_product_specifications
구조화된 사양과 저장된 Specification Sheet 텍스트를 반환. 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
하이브리드 관련 후보(벡터 + 카테고리/용도/사양). match_score, confidence, score_breakdown, match_reasons 포함. 선택적 debug=true.
find_upsell_products
하이브리드 업셀 후보. 측정 가능한 개선 필요(가격만으로는 부족). 사유는 upgrade_reasons에 포함.
find_cross_sell_products
하이브리드 교차판매 후보. 호환성이 우선이며 동일 계열 대체품은 제외.
추천 도구는 원본 제품을 제외하고 후보를 중복 제거함. Claude는 후보 풀을 요청한 다음 최종 3개 관련 / 4개 업셀 / 7개 교차판매를 직접 선택해야 함.
예시 워크플로
사용자: https://en.staging.lumenco.ca/brand/aaled의 처음 10개 제품을 분석하고 관련 3개, 업셀 4개, 교차판매 7개를 제공.
get_listing_products(listing_url=..., limit=10)각 원본에 대해
get_product(product_id=...)limit=10으로find_related_products/find_upsell_products/find_cross_sell_productsClaude가 후보 풀에서 최종 세트 선택
프로덕션 배포
MCP HTTPS 엔드포인트만 노출. PostgreSQL은 비공개로 유지.
Internet → HTTPS → MCP server → private PostgreSQL적합한 호스트: Railway, Render, Google Cloud Run, AWS, Cloudflare.
요구 사항:
uvicorn/ Docker 이미지 앞에 HTTPS 종료 장치MCP_AUTH_TOKEN설정(베어러 미들웨어가 격리되어 추후 OAuth로 교체 가능)읽기 전용
DATABASE_URL/health상태 확인
포트 5432를 공개하지 말 것.
Claude 사용자 지정 커넥터
서버가 공개 HTTPS URL에서 접근 가능해진 후:
Claude에서 사용자 지정 커넥터 추가.
MCP URL:
https://your-host/mcp서버 이름이 Lumenco Product Database로 표시되어야 함.
MCP_AUTH_TOKEN으로 베어러 인증 구성 또는 미들웨어를 교체한 경우 OAuth 구성."Lumenco 데이터베이스에 현재 몇 개의 제품이 있나요?"라고 질문. Claude는
get_catalog_status를 호출해야 함.
로컬 테스트용 임시 공개 HTTPS: localhost:8000 앞에 Cloudflare Tunnel, ngrok 또는 유사 도구.
보안
execute_sql,fetch_url,run_command또는 크롤링 도구 없음SQLAlchemy 매개변수화 쿼리만 사용
쿼리 제한 적용
세션은 PostgreSQL에서
SET TRANSACTION READ ONLY로 열림비밀은 도구 오류에 반환되지 않음
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