Lumenco Catalog MCP Server
Lumenco カタログ(Phase 1 スクレイパー + Phase 2 MCP)
このリポジトリには2つのレイヤーがあります:
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 のストアフロントです。
エリア | 動作 |
ブランド |
|
ブランドリスト |
|
製品 |
|
仕様シート | 通常は |
サイトマップ |
|
GraphQL |
|
フェッチ | 製品ページはサーバーレンダリングです。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 を1回押すと、正常に一時停止します。再度実行します:
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(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デフォルトのクロールモードは開発です:最大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)は、英語ホストの共有ヘッダーにまだ表示されます。それらはそこで 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
エンドツーエンドのプロンプト
docs/claude-e2e-tests.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 製品データベース 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)。カタログが入力されるようにクロールを実行する。
MCP の追加機能がまだ
requirements.txtにない場合はインストールする:
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>8 つのツールがすべて一覧表示され、実行可能であることを確認する。
利用可能なツール
すべてのツールは 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 は候補プールをリクエストし、最終的な Related 3 件 / Upsell 4 件 / Cross-sell 7 件を自身で選択する必要がある。
ワークフロー例
ユーザー: https://en.staging.lumenco.ca/brand/aaled の最初の 10 製品を分析し、Related 3 件、Upsell 4 件、Cross-sell 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