Skip to main content
Glama
ai-code-co

Lumenco Catalog MCP Server

by ai-code-co

Lumenco カタログ(Phase 1 スクレイパー + Phase 2 MCP)

このリポジトリには2つのレイヤーがあります:

  1. Phase 1https://en.staging.lumenco.ca/ をスクレイピングして PostgreSQL に取り込みます。

  2. 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 のストアフロントです。

エリア

動作

ブランド

https://en.staging.lumenco.ca/brand に全ブランドが一覧表示されます(Amasty Brands)。そのページのブランドカードは staging.lumenco.ca を指すことがよくあります。スクレイパーはそれらを英語ホストに書き換えます。

ブランドリスト

https://en.staging.lumenco.ca/brand/{slug} に Magento のページネーション ?p=2 付き(1ページ24製品)。総ページ数は #am-page-count にあります。

製品

/aaled-aa-900018-1x4-bl.html のような正規 URL。サーバーレンダリングされた HTML には JSON-LD、SKU、価格、在庫、仕様テーブル、Specification Sheet リンクが含まれます。

仕様シート

通常は /dev/*.pdf 配下の同一オリジン PDF です。

サイトマップ

/sitemap.xml は現在 HTTP 500 でエラーになります。クローラーは既知のサイトマップパスを試した後、ブランド + カテゴリの発見にフォールバックします。

GraphQL

/graphql は存在しますが、ステージングのスキーマは壊れています(Config element "String" is not declared)。HTML クローリングが信頼できる情報源です。

フェッチ

製品ページはサーバーレンダリングです。Scrapling の HTTP FetcherSession がデフォルトです。AsyncDynamicSession は、製品ページに必須フィールドが欠けている場合の遅延フォールバックとして登録されています。

クローラーは 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.sql

1. 依存関係のインストール

Python 3.10+ が必要です。

python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate

pip install -r requirements.txt

Scrapling の HTTP/ブラウザ拡張は scrapling[fetchers] に含まれています。ブラウザフォールバック(DynamicFetcher)が必要な場合は、ブラウザバイナリをインストールしてください:

scrapling install

スキャンされた画像のみの仕様 PDF 用のオプションの OCR:

pip install pytesseract Pillow
# plus a Tesseract OCR engine on the host

OCR はデフォルトでオフです(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 head

3. 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.html

4. 完全なクロールを実行

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=true

5. クロールの再開

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 など。

次にパイプライン:

  1. ドキュメント URL を保存します。

  2. httpx でファイルをダウンロードします(ブラウザではありません)。

  3. PDF のマジックバイト(%PDF)を検証します。

  4. 決定的なコピーを保存します:data/specifications/{sku}_{hash16}.pdf

  5. PyMuPDF でテキストを抽出します。

  6. ページ/セクションの区切りを維持しながら空白をクリーンアップします。

  7. 抽出されたテキスト、SHA-256 ハッシュ、メソッド、ステータスを保存します。

  8. PDF から Label: Value 行をフィールドを発明せずに解析します。

  9. 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. 失敗した製品のトラブルシューティング

症状

対処方法

python -m scraper validate が問題を報告

JSON の issues リストを読んでください(missing_nameinvalid_urlempty_extracted_text など)。

製品が HTTP 5xx / タイムアウトで失敗

python -m scraper crawl --resume を再実行してください。失敗は crawl_errors にあります。

Specification Sheet がない

一部の SKU では想定内です。ステータスは not_found で、製品行は引き続き保存されます。

PDF が ocr_required とマーク

OCR 拡張を有効にするか、data/specifications/ の保存ファイルを確認してください。

PDF が invalid_pdf とマーク

リンクされたファイルが PDF ではありませんでした(HTML エラーページなど)。specification_documents.error_message を確認してください。

重複製品

発生しないはずです:一意の product_url / canonical_url / sku に加えて upsert。validate を実行してください。

ブランドページが空に見える

en.staging.lumenco.ca にいることを確認してください。フランス語ホストではありません。スパイダーはこれを自動的に書き換えます。

DynamicFetcher エラー

scrapling install を実行してください。現在のステージング HTML には HTTP フェッチで十分です。

データベース接続エラー

DATABASE_URLdocker compose pspython -m scraper init-db を確認してください。

構造化ログは次のようになります:

[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_specificationsinclude_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 L0110TUT8002020

Phase 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

セットアップ

  1. pgvector を含む Postgres イメージを使用します(docker-compose.ymlpgvector/pgvector:pg16 を使用)。

  2. .env に埋め込み環境変数を設定します(.env.example を参照)。

  3. マイグレーション:

python -m alembic upgrade head
  1. 開発カタログの埋め込みを生成:

python -m scraper embeddings --limit 100
python -m scraper embedding-stats

変更されていない製品は content_hash でスキップされます。--force を使用してすべてを再生成します。

インデックス戦略

コサイン距離の HNSW(vector_cosine_opsm=16ef_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_productsfind_upsell_productsfind_cross_sell_productsRecommendationService(読み取り専用)を呼び出します。

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_WEIGHTUPSELL_TECHNICAL_WEIGHTCROSS_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 への接続

  1. docker compose up -d postgres

  2. python -m app.server

  3. クライアントを http://localhost:8000/mcp(Streamable HTTP)に向ける

  4. 任意: 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. フェーズ 1 のセットアップを完了する(PostgreSQL + .env + python -m alembic upgrade head)。

  2. カタログが入力されるようにクロールを実行する。

  3. MCP の追加機能がまだ requirements.txt にない場合はインストールする:

pip install -r requirements.txt
  1. .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_URLlumenco_mcp に向ける。

実行

python -m app.server

または:

uvicorn app.server:app --host 0.0.0.0 --port 8000

Docker:

docker compose up --build mcp

MCP エンドポイント

http://localhost:8000/mcp

ヘルスチェック

GET http://localhost:8000/health

{
  "status": "ok",
  "service": "lumenco-product-mcp",
  "database": "connected"
}

MCP Inspector

npx -y @modelcontextprotocol/inspector

トランスポート Streamable HTTPhttp://localhost:8000/mcp に接続する。MCP_AUTH_TOKEN が設定されている場合は、次を追加する:

Authorization: Bearer <token>

8 つのツールがすべて一覧表示され、実行可能であることを確認する。

利用可能なツール

すべてのツールは PostgreSQL のみを読み取る。Lumenco の URL を取得するものはない。

get_catalog_status

カタログのサイズと最新のクロールの鮮度。入力なし。

get_listing_products

ブランド / カテゴリの一覧 URL 上の製品を、元の一覧の位置順で取得。

入力

必須

備考

listing_url

はい

正規化され、データベースキーとして使用される

limit

いいえ

デフォルト 20、最大 100

offset

いいえ

デフォルト 0

get_product

product_id および / または sku による完全な製品レコード。

get_product_specifications

構造化された仕様に加え、保存されている Specification Sheet のテキスト。PDF はダウンロードしない。

search_products

ローカルカタログ検索(SKU、名前、ブランド、カテゴリ、説明、仕様)。

任意のフィルター: brandcategorysubcategoryskumin_pricemax_price

search_similar_products

保存された pgvector 埋め込みからの意味的類似製品(コサイン類似度)。埋め込みの生成や LLM の呼び出しは行わない。

任意のフィルター: brandcategorysubcategorymin_pricemax_price

ハイブリッドな 関連商品 候補(ベクトル + カテゴリ / 用途 / 仕様)。match_scoreconfidencescore_breakdownmatch_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 件を提示してください。

  1. get_listing_products(listing_url=..., limit=10)

  2. 各ソースに対して get_product(product_id=...)

  3. limit=10find_related_products / find_upsell_products / find_cross_sell_products

  4. Claude は候補プールから最終セットを選択する

本番デプロイ

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 で到達可能になった後:

  1. Claude でカスタムコネクタを追加する。

  2. MCP URL: https://your-host/mcp

  3. サーバー名は Lumenco Product Database と表示されるはず。

  4. MCP_AUTH_TOKEN でベアラー認証を設定するか、ミドルウェアを置き換えた場合は OAuth を設定する。

  5. 質問する: 「Lumenco データベースには現在何製品ありますか?」 Claude は get_catalog_status を呼び出すはず。

ローカルテスト用の一時的な公開 HTTPS: localhost:8000 の前段に Cloudflare Tunnel、ngrok など。

セキュリティ

  • execute_sqlfetch_urlrun_command、クロールツールはなし

  • SQLAlchemy のパラメータ化クエリのみ

  • クエリ制限を適用

  • セッションは PostgreSQL で SET TRANSACTION READ ONLY を開く

  • シークレットはツールエラーで返されない

F
license - not found
Not graded
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

  • 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.

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/ai-code-co/Claude_MCP_Lumenco'

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