labellevie

labellevie

MCP server for La Belle Vie grocery that lets an AI agent search the catalog, manage the basket, reorder past orders, check delivery coverage and slots, and prepare a ready-to-pay checkout summary without automating payment.

Category
访问服务器

README

La Belle Vie — Grocery MCP server

An MCP server (plus an optional thin lbv CLI) that lets an AI agent do the groceries on labellevie.com — search the catalog, fill the basket, reorder past shops, check delivery coverage and slots, and assemble a ready-to-pay summary. It is built on the private JSON API the website itself uses (backend: Deleev). This repo is a blueprint for a remote MCP server for La Belle Vie: deploy it as-is on Vercel, or swap the src/lbv/* client layer to bring another service to your agent.

Payment is never automated. Every flow stops at a ready-to-pay basket and hands you a summary plus the labellevie.com/panier link. There is deliberately no tool that places or pays for an order, and no card data is ever handled. You review and pay yourself on the site.

How it works

Claude connector ──MCP (OAuth via Descope, email OTP)──┐
                                                        ├─▶ Vercel: MCP server  (/mcp)
lbv CLI / agent ──MCP (static bearer LBV_API_TOKEN)─────┘        mcp-handler + withMcpAuth
                                                                 tool handlers ─▶ src/lbv/* core
                                                                          │
                                                    per-caller connection in Vercel KV:
                                                    AES-encrypted LBV login + cookie jar
                                                    (connected once via /connect/<code>)
                                                                          ▼
                                                    labellevie.com  +  search.deleev.com

Both the agent and the CLI speak MCP to the same deployed server. Your La Belle Vie login is not a server env var: each caller connects their own account once through a one-time browser link (connect_account). The server verifies the login against labellevie.com, then stores the session cookie jar plus the credentials encrypted with AES-256-GCM (LBV_CRED_KEY) in Vercel KV so it can transparently re-login when the cookie expires. The client-facing La Belle Vie logic is written once in src/lbv/* and both surfaces are thin.

Tools

Tool Auth What it does
search_products(query, page?, perPage?, categoryId?) — Search the catalog (id, name, price, unit, stock, sale, categories); categoryId keeps only products in that category or its subcategories
browse_categories(parentId?, query?) — Explore the taxonomy: no args → top-level aisles; parentId → subcategories; query → find categories by name
view_cart() — Show the current basket
add_to_cart(productId, quantity?) — Add a product
remove_from_cart(productId, quantity?) — Remove / reduce a product
empty_cart() — Empty the basket
check_postal_coverage(postalCode) — Is a postcode served + fees
get_delivery_slots(postalCode) — Available delivery windows + fees
verify_promo(code) connect Validate a promo code
list_recent_orders() connect Recent orders (reorder sources)
list_usual_products() connect Most-ordered products
reorder(orderId) connect Add every product from a past order into the basket
prepare_checkout(postalCode, slotKey?) — Ready-to-pay summary (totals, coverage, recommended slot, stock check, basket URL). Does NOT pay.
connect_account() — One-time secure browser link to connect your LBV account — the password never passes through the chat
connection_status() — Show whether (and which) LBV account is connected
disconnect_account() — Disconnect and delete the stored encrypted credentials + session

connect = needs a connected account (see Connect your account).

How the agent should shop

Keyword search alone can conflate meanings — search_products("banane") returns fresh bananas and banana-flavored candy. When a query is ambiguous (or you want to explore an aisle you don't know the French keywords for), call browse_categories first: no arguments lists the store's top-level aisles, parentId drills into one, query finds a category by name. Then pass the category id as categoryId to search_products to keep only products in that category (or any of its subcategories). The search gateway paginates before this filter, so a filtered page reports filteredCount/scannedCount and can legitimately come back empty — try the next page or a broader category.

Connect your account

Tools marked connect act on your La Belle Vie account. Instead of a shared login in server env vars, each caller connects their own account once:

  1. Ask the agent to run connect_account (CLI: lbv connect). It returns a link like https://<server>/connect/<code> — valid 10 minutes, single use, bound to your verified (OAuth or static-token) identity.
  2. Open the link and enter your labellevie.com email + password on that page. The credentials go from your browser to this server to labellevie.com — never through the chat or the model.
  3. On success the server keeps the authenticated cookie jar plus your credentials encrypted with AES-256-GCM (LBV_CRED_KEY) in KV, so it can silently re-login when the session cookie expires. The connection lives 90 days past its last use (rolling), i.e. effectively until you disconnect.

connection_status shows what is connected; disconnect_account deletes the stored credentials and session. A wrong password can be retried up to 5 times per link; an expired or used link shows a clear page telling you to ask the agent for a fresh one. Static-bearer (CLI) callers share one connection; each OAuth user gets their own isolated connection.

Use it from an agent

Two independent auth paths hit the same /mcp endpoint: OAuth (Descope, for Claude Desktop/claude.ai connectors) and a static bearer token (for the CLI and any MCP client that supports headers).

Claude Desktop / claude.ai (OAuth custom connector):

  1. Settings → Connectors → Add custom connector → URL https://mcp-server-labellevie.vercel.app/mcp.
  2. Click Connect — a Descope sign-in opens. Enter the allow-listed email and the one-time code it receives.
  3. Approve the consent screen; the tools appear.

Sign-in is by email one-time code and access is restricted server-side to a single allow-listed address (LBV_ALLOWED_EMAIL): any other account — even one that completes the Descope flow — is rejected with a 401. Self-registration is blocked in Descope besides.

Claude Code:

claude mcp add --transport http labellevie https://mcp-server-labellevie.vercel.app/mcp \
  --header "Authorization: Bearer $LBV_API_TOKEN"

Generic MCP JSON config:

{
  "mcpServers": {
    "labellevie": {
      "type": "http",
      "url": "https://mcp-server-labellevie.vercel.app/mcp",
      "headers": { "Authorization": "Bearer <LBV_API_TOKEN>" }
    }
  }
}

Use it from the CLI

The lbv CLI is a thin MCP client — it holds no secrets beyond the bearer token and talks to the same server.

npm run build:cli          # produces dist/cli.js (the `lbv` bin)

export LBV_MCP_URL="https://mcp-server-labellevie.vercel.app/mcp"
export LBV_API_TOKEN="…"

lbv search "banane bio" --perPage 5
lbv categories                     # top-level aisles
lbv categories 74                  # subcategories of category 74
lbv categories --find fromage      # find categories by name
lbv search banane --category 74    # keyword search filtered to a category
lbv add 49135 2
lbv cart
lbv slots 75011
lbv connect                   # one-time browser link to connect your LBV account
lbv status                    # which account is connected
lbv reorder 123456
lbv checkout 75011            # ready-to-pay summary; never pays
lbv disconnect                # delete the stored credentials + session
lbv <command> --json         # print the structured JSON result instead of text
lbv --help

Local development

npm install
npm run dev                  # Next.js dev server → http://localhost:3000/mcp

# Inspect the tools interactively:
npx @modelcontextprotocol/inspector      # point it at http://localhost:3000/mcp + your bearer

# Or drive it with the CLI against local dev:
LBV_MCP_URL=http://localhost:3000/mcp LBV_API_TOKEN=dev-token lbv search "lait"

Health check (no auth): GET /api/health reports liveness and whether the bearer token / OAuth / KV / LBV_CRED_KEY are configured, plus connectReady (KV and key present — the account-connect flow will work). It never returns secrets.

Environment variables

Server variables go in the Vercel project; LBV_EMAIL/LBV_PASSWORD live only in your local .env.local (gitignored) for verify-auth / integration tests:

Variable Purpose
LBV_EMAIL, LBV_PASSWORD Local only (verify-auth + integration tests). The server never reads them — never set on Vercel.
LBV_CRED_KEY AES-256-GCM key encrypting connected users' credentials at rest (openssl rand -hex 32). Rotating it forces everyone to reconnect.
LBV_API_TOKEN Bearer token checked by the server; also given to the agent / CLI
DESCOPE_PROJECT_ID Descope project id — enables the OAuth path (not a secret)
LBV_ALLOWED_EMAIL The OAuth security boundary: only a token with this email claim is accepted (fail-closed)
LBV_ALLOWED_SUBJECT Same boundary keyed on the Descope user id (U…) in sub — covers tokens without an email claim; either match suffices
DESCOPE_BASE_URL Optional Descope regional base URL (default https://api.descope.com)
DESCOPE_MANAGEMENT_KEY Local descope CLI only — never on Vercel, never committed
KV_REST_API_URL, KV_REST_API_TOKEN Vercel KV — account connections, one-time connect links, cookie jars. Required in production; the in-memory fallback is local-dev only.
REDIS_URL Optional — backs mcp-handler SSE resumability
LBV_MCP_URL CLI only — the server URL (default http://localhost:3000/mcp)

See .env.example.

Verify auth

To confirm the login handshake works with your credentials (the same handshake the /connect page uses), locally:

# put LBV_EMAIL / LBV_PASSWORD in .env.local first
npm run verify-auth

This performs the real login + an authenticated GET /api/fullprofile. Your password is read locally and sent only to labellevie.com — never printed or committed.

Testing

npm run lint                 # ESLint (flat config)
npm run typecheck            # tsc --noEmit
npm test                     # unit + contract tests (mocked, no secrets, no network)
npm run test:integration     # opt-in live tests — needs LBV_LIVE=1 + LBV_EMAIL/LBV_PASSWORD
  • Unit (tests/unit): request builders + response parsers grounded in captured API fixtures, the CSRF login handshake + auto re-login, and the session store.
  • Contract (tests/contract): starts the MCP server in-process and asserts the exact tool set, each tool's input schema, and — as a guardrail regression — that no payment/order-placing tool is exposed.
  • Integration (tests/integration): read-only / self-reverting live calls (search, coverage, slots, and an add→view→remove cart round-trip that restores the basket). Never touches payment. Skipped unless LBV_LIVE=1.

CI/CD & branches

  • main = production (protected), dev = staging. Flow: feature branch → PR → dev → PR → main.
  • .github/workflows/ci.yml (push/PR to dev & main): install → lint → typecheck → test → build. Fully mocked, no secrets — this is the merge gate.
  • .github/workflows/integration.yml (manual, via Run workflow): runs the live tests with the repo secrets LBV_EMAIL / LBV_PASSWORD. Kept off the PR path so a flaky external API never blocks a merge.

Deploy (Vercel)

Deployment uses Vercel's native Git integration (one-time setup):

  1. Import this repo into a Vercel project.
  2. Set the environment variables above (LBV_API_TOKEN, LBV_CRED_KEY, DESCOPE_PROJECT_ID, LBV_ALLOWED_EMAIL, KV). Do not set LBV_EMAIL/LBV_PASSWORD — if migrating from an older deploy, delete them. Env changes only apply to new deployments — redeploy after changing them.
  3. Add a Vercel KV (Upstash Redis) store to the project (required for the connect flow).
  4. Push dev → Preview deploy; PR dev → main → Production deploy.
  5. From each MCP client, run connect_account once and complete the browser login.

Add the same LBV_EMAIL / LBV_PASSWORD as GitHub Actions secrets to enable the integration workflow.

Notes & limitations

  • This automates your own account through the app's private, undocumented API. Keep it to personal use and gently rate-limited. Undocumented endpoints can change without notice; /api/health helps flag breakage early.
  • Payment is out of scope by design — the tool stops at a ready basket and you complete payment.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选