# Kapruka MCP (remote · mcp.kapruka.com)

Free public MCP server for Kapruka.com — Sri Lanka's largest e-commerce platform.

- Trust score: 69/100 (medium)
- Change this week: +9
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `mcp.kapruka.com`: 69/100 (this document), [markdown](https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp.md), [page](https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp)

## Channel facts

- Endpoint: `https://mcp.kapruka.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.3`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 80/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 56/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3028 tokens (~432/item across 7 items; 7 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http com-kapruka-kapruka-mcp https://mcp.kapruka.com/mcp
```

### Codex

```toml
[mcp_servers.com-kapruka-kapruka-mcp]
url = "https://mcp.kapruka.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com-kapruka-kapruka-mcp": {
      "type": "remote",
      "url": "https://mcp.kapruka.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com-kapruka-kapruka-mcp --url https://mcp.kapruka.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  com-kapruka-kapruka-mcp:
    url: "https://mcp.kapruka.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "com-kapruka-kapruka-mcp": {
      "type": "http",
      "url": "https://mcp.kapruka.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 68, +6)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 62, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 62, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-28 (score 61, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 60, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 60)

First indexed and scored.

## MCP tools (7)

### `kapruka_list_categories` (~239 tokens)

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.

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_get_product` (~449 tokens)

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, and a direct product URL.

    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. 'cake00ka002034')
            - 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],              # list of full-resolution image URLs
          "attributes": {"type": str, "subtype": str, "weight": str, "vendor": str},
          "shipping": {"ships_from": str, "ships_internationally": bool, "restricted_countries": [str]},
          "rating": null,
          "url": str
        }

        Error: "Error: <message>" on failure.

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_search_products` (~622 tokens)

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.

    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' (default) or 'json'

    Returns:
        str: Search results in the requested format.

        JSON schema:
        {
          "results": [
            {
              "id": str,
              "name": str,
              "summary": str,
              "price": {"amount": float | null, "currency": str},
              "compare_at…

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_list_delivery_cities` (~233 tokens)

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
        }

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_check_delivery` (~360 tokens)

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.

    If a `product_id` is supplied and the code matches a perishable family
    (CAKE*, FLOWER*, COMBO*), an extra warning is added 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]): Optional, enables perishable warning
            - 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,
          "rate": number,                   # flat LKR rate per order
          "currency": "LKR",
          "reason": str | null,             # populated when available=false
          "next_available_date": str|null,  # populated when available=false
          "perishable_warning": str | null  # populated when product_id is perishable
        }

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_create_order` (~545 tokens)

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              # IS…

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

### `kapruka_track_order` (~512 tokens)

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": b…

Input parameters:

- `params` (required)

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp#diagnostics

## Score history

- 2026-08-03: 69
- 2026-08-02: 69
- 2026-08-01: 68
- 2026-07-31: 68
- 2026-07-30: 62
- 2026-07-29: 62
- 2026-07-28: 61
- 2026-07-27: 60
- 2026-07-26: 60

## Links

- Remote endpoint: https://mcp.kapruka.com/mcp
- Repository: https://github.com/kapruka/mcp
- Website: https://mcp.kapruka.com/
- Changelog RSS feed: https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/com-kapruka-kapruka-mcp/mcp
