Lumenco Catalog MCP Server
Lumenco Catalog(阶段 1 爬虫 + 阶段 2 MCP)
本仓库包含两层:
阶段 1 将
https://en.staging.lumenco.ca/抓取到 PostgreSQL。阶段 2 通过一个只读的 Model Context Protocol 服务器暴露该目录,使 Claude 无需浏览 Lumenco 即可检索产品、规格、列表和推荐候选。
CLAUDE
│ MCP / HTTPS
▼
Lumenco Product Database (Streamable HTTP)
│ tools → services → repositories
▼
PostgreSQL (Phase 1 catalog)阶段 1 抓取。阶段 2 暴露。Claude 推理。
MCP 服务器从不抓取 Lumenco,从不下载规格 PDF,从不调用 LLM,也从不写入数据库。
网站外观
Lumenco 暂存环境是一个 Magento 2 店面。
区域 | 行为 |
品牌 |
|
品牌列表 |
|
产品 | 规范 URL 如 |
规格表 | 通常是同源 PDF,位于 |
站点地图 |
|
GraphQL |
|
抓取 | 产品页面是服务端渲染的。Scrapling 的 HTTP |
爬虫停留在 en.staging.lumenco.ca 上。外部规格表 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 个,下载其规格表,将行存储到 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. 恢复抓取
通过 CRAWL_DIR(默认 ./data/crawl)启用 Scrapling 检查点。按一次 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. 规格表的处理方式
对于每个产品页面,解析器查找:
a.document-item-link(Lumenco 的“规格表”控件)等效标签:规格表、规格书、规格、技术数据、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 / 超时失败 | 重新运行 |
缺少规格表 | 某些 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,否则拒绝完整目录抓取。
阶段 2.5 — 100 产品数据质量
本项目当前针对受控的约 100 个产品的 Lumenco 数据集。实时目录有 30,000+ SKU;完整目录抓取有意不在范围内。
流程
Scrapling → 产品提取 → PDF 下载 → PDF 文本或 OCR → 规格标准化 → PostgreSQL → 只读 MCP
首先尝试 PDF 文本提取。仅当 PDF 没有有意义的文本时,才运行 OCR(通过 pytesseract 的 Tesseract)。设置 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 L0110TUT8002020阶段 3A — 向量搜索 + 产品嵌入
阶段 3A 通过 PostgreSQL + pgvector 添加语义产品表示。它不实现相关/升级/交叉销售排名(那是阶段 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。现有的推荐工具不变。
阶段 3B — 混合推荐引擎
推荐结合 pgvector 相似度 和 结构化产品规则。仅靠向量相似度不够:18W T8 灯管、30W T8 灯管和 T8 灯具可能在语义上接近,但它们分别映射到相关、升级和交叉销售。
Product → vector candidates + structured neighbors
↓
hard exclusions
↓
Related / Upsell / Cross-sell scorers
↓
scores + confidence + reasons → MCP类型 | 含义 |
相关 | 相似的使用场景 / 类别 / 规格 |
升级 | 同一系列 且 可衡量的改进(不仅仅是价格) |
交叉销售 | 互补(驱动器、装饰、外壳、灯具↔灯管) |
排名中不使用 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)。
阶段 3C — Claude + MCP 工作流
User → Claude → MCP (/mcp) → PostgreSQL + pgvector + RecommendationService → Claude → User职责
层 | 作用 |
Scrapling | 爬取 / 存储 |
PostgreSQL + pgvector | 数据源 + 向量 |
RecommendationService | 确定性推荐 / 关联/交叉销售排序 |
MCP | 只读(无写入工具) |
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+)有意不在范围内。
第二阶段 — Lumenco 产品数据库 MCP
名为 Lumenco 产品数据库 的只读 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本地设置
完成第一阶段设置(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对于生产环境,创建一个只读角色:
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。它们都不会抓取 Lumenco URL。
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
混合 相关 候选(向量 + 分类/应用/规格)。包含 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(bearer 中间件是隔离的,因此以后可以用 OAuth 替换)只读的
DATABASE_URL在
/health上进行健康检查
不要发布端口 5432。
Claude 自定义连接器
服务器在公共 HTTPS URL 上可达后:
在 Claude 中,添加一个自定义连接器。
MCP URL:
https://your-host/mcp服务器名称应显示为 Lumenco 产品数据库。
使用
MCP_AUTH_TOKEN配置 bearer 认证,或者如果您替换了中间件,则使用 OAuth。询问:“Lumenco 数据库中当前有多少产品?”Claude 应调用
get_catalog_status。
用于本地测试的临时公共 HTTPS:Cloudflare Tunnel、ngrok 或类似工具,放在 localhost:8000 前面。
安全
没有
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