
Kapruka MCP
Free public MCP server for Kapruka.com — Sri Lanka's largest e-commerce platform.
What it can do
What data it sees
Do you need an account
No: the server works without sign-in
Free public MCP server for Kapruka.com — Sri Lanka's largest e-commerce platform.
How to connect
How to connect Kapruka MCP to Claude
The server address to paste into Claude settings:
https://mcp.kapruka.com/mcp
- Open Claude (claude.ai or the desktop app).
- Go to Settings → Connectors.
- Click Add custom connector.
- Paste the server address copied below into Remote MCP server URL and click Add.
- In a chat, click + → Connectors and switch the new connector on.
Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.
Authorization
After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.
How to connect Kapruka MCP to ChatGPT
The server address to paste into ChatGPT settings:
https://mcp.kapruka.com/mcp
- Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
- Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
- Open Settings → Connectors and click Create.
- Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
- Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
- In a new chat open + → Apps/Connectors and enable the connector.
OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.
Authorization
On first use ChatGPT opens the service's sign-in window. Sign in and approve access.
How to connect Kapruka MCP to Cursor
The server address to paste into Cursor settings:
https://mcp.kapruka.com/mcp
Fastest: click Open in Cursor below and confirm the prompt.
Manually:
- In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
- Paste the JSON copied below into
~/.cursor/mcp.json(per project:.cursor/mcp.jsonin the repo root). - Save the file. The server appears in the MCP list; authorize it there if asked.
Authorization
If the service needs sign-in, an authorize button appears next to the server in the MCP list.
Server tool list (8)
Raw names from tools/list. Only developers need these.
| kapruka_list_categories | List top-level Kapruka product categories by name with browse URLs. Returns category names (usable as the `category` filter on kapruka_search_products) plus the public Kapruka.com URL for each category landing page — useful for shopping agents that want to send users directly to a category to browse. Internal IDs and product counts are not exposed. Results are cached for 30 minutes server-side. Args: params (ListCategoriesInput): - depth (int): Sub-category levels to include, 1 or 2 (default 1) - response_format (str): 'markdown' (default) or 'json' Returns: str: Category tree in the requested format. JSON schema: { "categories": [ { "name": str, "url": str, # kapruka.com category landing page "children": [{"name": str, "url": str, "children": [...]}] } ] } Error: "Error: <message>" on failure. |
| kapruka_get_product | Fetch full details for a single Kapruka product by its product ID. Returns name, description, price (with optional currency conversion), stock status, images, variants, shipping info, delivery scope, and a direct product URL. Delivery scope: most gifts ship island-wide, but restaurant food, hotel cakes and liquor only reach a limited city set (typically the Colombo area). The `delivery` object is the authority — search results do NOT carry it. When `delivery.island_wide` is false, tell the customer up front that the item is delivered only to selected cities, and confirm their city with kapruka_check_delivery(city, product_id) before promising anything. If `deliverable_city_count` exceeds the returned list, the list is truncated — say "and more", don't treat it as complete. Note: Some IDs starting with 'CATSYM' are category landing pages, not purchasable products — this tool will flag those clearly. Args: params (GetProductInput): - product_id (str): Kapruka product ID (e.g. 'cakeXX000000') - currency (str): Price currency — LKR (default), USD, GBP, AUD, CAD, EUR - type (Optional[str]): Optional type hint (e.g. 'specialgifts') - response_format (str): 'markdown' (default) or 'json' Returns: str: Product details in the requested format. JSON schema: { "id": str, "name": str, "description": str, "summary": str, "price": {"amount": float, "currency": str}, "compare_at_price": {"amount": float, "currency": str} | null, "in_stock": bool, "stock_level": str, # "low" | "medium" | "high" "category": {"id": str, "name": str, "slug": str, "path": str}, "variants": [{"id": str, "name": str, "sku": str, "price": {...}, "in_stock": bool, "stock_level": str, "attributes": {...}}], "images": [str], |
| kapruka_search_products | Search for products on Kapruka.com by keyword, with optional category filter and pagination. Returns a ranked list of matching products with prices, stock status, images, and URLs. Supports cursor-based pagination — pass next_cursor from one response into the next call. Pagination is capped at 3 pages per query to discourage catalog enumeration; for broader discovery, refine the query or filter by category instead. Queries must be at least 3 characters and contain specific terms — pure stopword queries (e.g. "the", "a an") are rejected. By default, category landing pages (CATSYM entries with price=0) are filtered out so results contain only purchasable products. Set include_stubs=true to include them. Search results carry NO delivery-scope information. Food, hotel cakes and liquor are delivered only to selected cities — never infer deliverability from a search hit. Before quoting delivery on a specific item, call kapruka_get_product (read `delivery.island_wide`) or kapruka_check_delivery with `product_id`. Args: params (SearchProductsInput): - q (str): Search query (e.g. 'birthday cake', 'roses', 'tea gift'). Min 3 chars. - category (Optional[str]): Category filter (e.g. 'Birthday', 'Flowers') - limit (int): Results per page, 1–50 (default 10) - cursor (Optional[str]): Pagination cursor from previous response - currency (str): LKR (default), USD, GBP, AUD, CAD, EUR - min_price (Optional[float]): Min price (inclusive) in the requested currency - max_price (Optional[float]): Max price (inclusive) in the requested currency - in_stock_only (bool): Restrict to in-stock items (default false) - sort (str): 'relevance' | 'price_asc' | 'price_desc' | 'newest' | 'bestseller' - include_stubs (bool): Include category landing pages (default false) - response_format (str): 'markdown' (d |
| kapruka_create_order | Create a guest-checkout order on Kapruka and return a click-to-pay link. Builds a Kapruka order from the supplied cart + recipient + delivery + sender, then returns a checkout URL the customer opens in a browser to complete payment. No Kapruka account is required. Prices are locked for the lifetime of the link (60 minutes) — the customer pays exactly the quoted grand total even if the catalog price changes meanwhile. Free public tier limits: 30 orders per hour per client IP. Cart up to 30 items, quantity up to 99 per item. A fresh idempotency key is generated per call so retries on transient errors return the same checkout URL rather than duplicates. Args: params (CreateOrderInput): - cart (list[CartItem]): 1–30 items. Each: product_id, quantity (default 1), optional icing_text (cakes only). - recipient (Recipient): name + phone (E.164 +9477… or local 077…) - delivery (Delivery): address, city (must be Kapruka-deliverable — use kapruka_list_delivery_cities), location_type (house/apartment/office/other, default house), date (YYYY-MM-DD, today-or-future Asia/Colombo), optional instructions - sender (Sender): name + anonymous flag - gift_message (Optional[str]): Up to 300 chars - currency (str): LKR (default), USD, GBP, AUD, CAD, EUR - response_format (str): 'markdown' (default) or 'json' Returns: str: Order confirmation with checkout URL. JSON schema: { "checkout_url": str, # Open in browser to pay (no login required) "order_ref": str, # e.g. "ORD-20260520-7823" "summary": { "items_total": number, "delivery_fee": number, "addons_total": number, "grand_total": number, # items_total + delivery_fee + addons_total "currency": str }, "expires_at": str # ISO |
| kapruka_track_order | Look up status and delivery progress for a Kapruka order by order number. Returns current status (received / confirmed / out-for-delivery / delivered / cancelled), the recipient and delivery details on file, a timestamped progress timeline, the cart contents, and flags for whether a delivery photo or video is available. Use this after a customer has placed and paid for an order and reads back the order number from their confirmation email or the order complete page. The order number is NOT the `order_ref` returned by kapruka_create_order (which is the pre-payment checkout reference). Once the customer completes payment in the browser, Kapruka emails them a separate order number — that is what this tool expects. Args: params (TrackOrderInput): - order_number (str): Kapruka order number (e.g. 'VIMP34456CB2') - response_format (str): 'markdown' (default) or 'json' Returns: str: Order tracking details in the requested format. JSON schema: { "order_number": str, "pnref": str, # internal payment reference (numeric; not the same as order_number) "status": str, # received | confirmed | shipped | delivered | cancelled | ... "status_display": str, # human label "order_date": str, # human-formatted, Asia/Colombo "delivery_date": str, # human-formatted "shipped_date": str | null, "amount": str, # LKR string (e.g. "15500.00") "payment_method": str, "comments": str | null, "recipient": {"name": str, "phone": str, "address": str, "city": str}, "greeting_message": str | null, "special_instructions": str | null, "progress": [{"step": str, "timestamp": str}], "live_tracking_available": bool, "has_delivery_video": bool, "has_delivery_photo": bo |
| kapruka_render_options_card | Render 1-4 products as ONE shareable JPEG "menu" card and return its URL. The card shows each product's photo with a big numbered badge (the ref you assign), and its name + price printed under the photo. Built for chat commerce (WhatsApp): send the image, tell the customer "reply 1, 2 or 3", and they pick without opening links. No AI is involved — the image is server-composited from the live catalog data, so prices match what the product tools return. Ref numbering contract: refs are yours to assign — use sequential numbers per conversation and NEVER reuse one (if the first card was 1-3, the next card starts at 4). A number must keep meaning the same product for the whole conversation. Args: params (RenderOptionsCardInput): - items (list[CardProduct]): 1-4 of {product_id, ref} - currency (str): LKR (default), USD, GBP, AUD, CAD, EUR Returns: str: JSON: { "card_url": str, # public JPEG URL — send this as the image "items": [{"ref": int, "product_id": str, "name": str, "price": {"amount": float, "currency": str}, "url": str}], "unavailable": [str] # product_ids that failed to load (omitted from card) } Error: "Error: <message>" when no product could be loaded. |
| kapruka_list_delivery_cities | List or search Sri Lankan cities Kapruka delivers to. Use the `query` param to filter (e.g. "colombo" → all Colombo zones, "anur" → Anuradhapura). Without a query you get the first 25 cities alphabetically, which is rarely what an agent needs — pass a query. Returns canonical city names (use these as the `city` argument to kapruka_check_delivery) plus any common aliases / vernacular spellings. Args: params (ListDeliveryCitiesInput): - query (Optional[str]): Partial match filter - limit (int): Max results, 1–50 (default 25) - response_format (str): 'markdown' (default) or 'json' Returns: str: Cities list in the requested format. JSON schema: { "cities": [{"name": str, "aliases": [str]}], "total_matched": int, "showing": int } |
| kapruka_check_delivery | Check whether Kapruka can deliver to a given city on a given date, and at what rate. Returns the flat delivery rate (LKR), whether the requested date is available, and — if not — the next available date plus reason. Kapruka delivers as a single shipment per order at one flat rate regardless of item count. Pass `product_id` whenever the customer has named a product: the answer then also checks that ITEM's delivery scope (restaurant food, hotel cakes and liquor only reach selected cities, typically the Colombo area). With a product_id, `available` is true only if the date is open AND the item is deliverable to that city. When `item_deliverable` is false, offer the customer one of the returned `deliverable_cities` or an island-wide alternative — do not attempt kapruka_create_order with the same city, it will be rejected. An unknown product_id is silently ignored (no item fields in the result), so check `item_deliverable` is present before relying on it. Perishable codes (CAKE*, FLOWER*, COMBO*) additionally get a freshness warning when the chosen delivery date is more than 1 day out. Args: params (CheckDeliveryInput): - city (str): Canonical city name (e.g. 'Colombo 03', 'Galle') - delivery_date (Optional[str]): YYYY-MM-DD; defaults to today (LK time) - product_id (Optional[str]): Check the city against this item's delivery scope - response_format (str): 'markdown' (default) or 'json' Returns: str: Delivery feasibility + rate in the requested format. JSON schema: { "city": str, "now": str, # ISO timestamp, Sri Lanka time "checked_date": str, # YYYY-MM-DD "available": bool, # date open AND (if product_id) item deliverable "rate": number, # flat LKR rate per order "currency": "LKR", "reas |