Lift-Spares Parts Finder
OfficialAuthenticates the signed-in customer with Cloudflare Access (Managed OAuth) in front of the host: Cloudflare serves the OAuth discovery and the 401 for anonymous clients and forwards a Cf-Access-Jwt-Assertion header, which the server validates on every request against the Cloudflare Access team domain, AUD tag and JWKS (RS256, aud, iss — with an optional override of the /cdn-cgi/access/certs endpoint for tests).
Provides ordering and catalog links for lift spare parts through the Lift-Spares Shopify store: product pages (storefront_url) and Shopify cart permalinks (https://lift-spares.se/cart/:1) built from Shopify variant IDs, catalog data such as shopify_status and shopify_variant_id, and sign-in via Shopify customer accounts. The README also points to the store's own Shopify Universal Commerce Protocol MCP endpoint (https://lift-spares.se/api/ucp/mcp) for catalog, cart and checkout.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Lift-Spares Parts Finderfind the KONE door roller part number KM587123G01 for me"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Lift-Spares Parts Finder (MCP server)
A public MCP server from Lift-Spares (Elegant Lift Sweden AB). Add it to the AI assistant you already use and it identifies lift (elevator) spare parts in the Lift-Spares catalog: by part number, description, make, model or part type, in any language. Ordering happens on the website; the server hands you the product page and a cart link. Parts that are in the catalog but not on the website, or not in the catalog at all, can be requested from the same chat.
Endpoint: https://mcp.lift-spares.se/mcp (streamable HTTP).
Sign in
When you add the server, your assistant opens a sign-in page: sign in with your Lift-Spares customer account (the same e-mail + one-time code as on lift-spares.se). No API keys. If you do not have an account, create one at https://lift-spares.se/account first.
Related MCP server: Ecomm MCP Server
Add it to your assistant
Assistant | How |
Claude.ai / Claude desktop | Settings → Connectors → Add custom connector → URL |
Claude Code |
|
ChatGPT (developer mode) | Settings → Connectors → Create → MCP server URL |
Cursor | Settings → MCP → Add new global MCP server: |
Any other MCP client that supports streamable HTTP with OAuth (dynamic client registration) works the same way.
The three tools
liftspares_search_parts(query, max_rows=10)
Search by the customer's own words in any language. Word search and meaning search run together; an exact part number comes first with at most five possible alternatives.
> search KM587123G01
items: [{product_uid: "P142409", manufacturer: "KONE", title: "KONE door roller ...", sku: "KM587123G01",
listing: "shop", storefront_url: "https://lift-spares.se/en/products/...", cart_url: "https://lift-spares.se/cart/<variant>:1",
found_by: "words", relevance: 0.97, matched_in: "KM587123G01 in own part number"}, ...]
count: 3, total_word_matches: 3, note: null, next_step: "..."listing: "shop"— on the website;storefront_urlis the product page,cart_urladds one to the cart.listing: "catalog"— in the Lift-Spares database but not on the website: requestable withliftspares_request_partand itsproduct_uid.total_word_matcheslarger thancountmeans the list was cut: search again with one more word.No prices and no stock levels, by design: they are on the product page.
liftspares_get_part(product_uid)
One part's full identification row: all titles, all identifiers, barcode, vendor, type, tags, description,
HS code, weight, country of origin, listing and links. Unknown product_uid is an error.
liftspares_request_part(description, product_uid?, manufacturer?, part_number?, quantity?, searched?)
Ask Lift-Spares for a part that is not on the website. The request is recorded for the Lift-Spares team and you
get a reference (D-123). No order is placed and no reply arrives in the chat; Lift-Spares reads the requests and
adds parts to the website.
Ordering
The server never orders. It gives you the product page (storefront_url) and Shopify's cart permalink
(cart_url, https://lift-spares.se/cart/<variant>:1); price, availability and checkout are on lift-spares.se.
Agents that speak Shopify's Universal Commerce Protocol can also use the store's own MCP endpoint,
https://lift-spares.se/api/ucp/mcp (catalog, cart, checkout), which this server does not wrap.
Privacy
Every search, lookup and request is recorded together with the signed-in customer's id, the client name and version, the MCP session id and the user agent, to improve the catalog: parts people look for and Lift-Spares does not carry are what gets added next. No e-mail address, name or IP address is stored with the lookups. Traces may be kept in Lift-Spares' own Langfuse instance for the same purpose. Contact: https://lift-spares.se/pages/contact.
Self-hosting
The code is small on purpose: server.py (three tools), hybrid.py (the search: word search + meaning search +
reranker, the same file the Lift-Spares chat uses), auth.py (Cloudflare Access JWT), catalog.py (Postgres),
demand.py (request/lookup recording), trace.py (Langfuse, optional).
uv sync --frozen
cp deploy/service.env.example service.env # fill in
uv run python server.pyEnvironment (see deploy/service.env.example):
Variable | Meaning |
| bind address (default |
| Postgres DSN of the read-only role (see Database contract) |
| Cloudflare Access team domain, e.g. |
| the Access application's AUD tag (JWT audience) |
| optional override of |
| dotted path to the customer id in the JWT claims, default |
| lookups per customer per minute; above it the next call is refused for a minute (default 60) |
| the LiteLLM proxy serving the embedding and rerank models |
| model names on that proxy (empty rerank model = no rerank stage) |
| optional tracing; unset keys = no tracing |
Authentication is not in this code: Cloudflare Access (Managed OAuth) in front of the host signs the customer in
with the Shopify customer account (generic OIDC identity provider), serves the OAuth discovery and the 401 for
anonymous clients, and forwards Cf-Access-Jwt-Assertion to the origin. auth.py validates that JWT (RS256,
JWKS, aud, iss) on every request and refuses everything else. A systemd unit is in deploy/.
Database contract
The server needs one login role with SELECT on the view chatkit_public.product (price-free: product_uid, manufacturer, shop_title, canonical_title, sku, primary_code, all_titles, all_identifiers, barcode, vendor, product_type, tags, description_html, hs_code, weight, country_of_origin, featured_image_url, storefront_url, shopify_status, shopify_variant_id) and EXECUTE on:
chatkit_public.find(words text, max_rows int)— the word search (product_uid, manufacturer, canonical_title, primary_code, sku, all_identifiers, product_type, shopify_status, storefront_url, words_matched, words_searched, matched_in, score, total_matches);chatkit_public.find_similar(query_vec halfvec, max_rows int)— the meaning search, same columns;demand.record(jsonb) RETURNS (id bigint, recent_count int)— inserts one lookup row and returns the caller's lookups in the last 60 s (the rate limiter). It refuses payloads carrying personal-data keys.
Statement timeouts are a role setting (ALTER ROLE ... SET statement_timeout), not code.
Tests
uv run pytestUnit tests only: an in-test RS256 key pair stands in for Cloudflare Access, fakes stand in for Postgres and
LiteLLM; tests/test_no_secrets.py guards the tree against committed keys.
License
Apache-2.0, Copyright 2026 Elegant Lift Sweden AB.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hard-to-source part discovery with replacement, salvage and fabrication paths.
MCP server for IT hardware parts research: normalize PNs, search listings, get subs/comps.
Find products by description or Bill of Materials, over 100k+ suppliers and products
Search real parts with datasheet-provenance specs, check compatibility and compose priced BOMs.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables searching for electronic components through the Nexar Supply API, providing detailed part information including manufacturer, pricing, specifications, and datasheets.-
- AlicenseNot gradedqualityDmaintenanceEnables product search and retrieval from e-commerce APIs, returning markdown-formatted product listings with clickable links and prices for easy shopping assistance.12 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables searching and retrieving detailed product specifications from McMaster-Carr using part numbers or search queries.MIT
- AlicenseNot gradedqualityDmaintenanceEnables searching and retrieving detailed information on electronic components from TME, including pricing, stock, datasheets, and delivery estimates.1MIT