Skip to main content
Glama

kapruka_create_order

Idempotent

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 lines. Catalogue line: product_id, quantity (default 1), optional icing_text (cakes only).
          Custom cake line: custom_cake_request_id + phone — orders the cake Kapruka staff quoted via
          kapruka_custom_cake_status (status must be 'quoted'; quantity is always 1; never send a price).
          Lines can be mixed in one order — one delivery fee covers everything; the whole cart must be
          deliverable to delivery.city. Only place a custom cake order after the customer clearly
          accepted the quoted total.
        - 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, 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"
      "order_id": str,               # id used by the bank-deposit flow
      "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 8601 — link stops working after this
    }

    Error: "Error (<code>): <message>" on failure. Common codes:
      empty_cart, missing_field, past_delivery_date, product_not_found,
      product_out_of_stock, city_not_deliverable (city not in the network at
      all), date_not_deliverable, city_not_deliverable_for_item.

    Custom cake lines add: request_not_found (404 — wrong id/phone or staff
    removed it), quote_not_ready (409 — staff haven't priced it; check
    kapruka_custom_cake_status later), quote_expired (410 — submit a new
    kapruka_custom_cake_request). summary.items_total may differ from the
    quoted cake total by a few rupees (USD round-trip) — quote the summary
    numbers when asking for payment.

    city_not_deliverable_for_item (HTTP 422): at least one cart item (food /
    hotel cake / liquor) cannot reach delivery.city. NOTHING is created — the
    API never places a partial order and neither should you. The error text
    names every blocking item and lists the cities the whole cart CAN go to.
    Tell the customer which item blocks the order and offer to (a) change the
    city to one of those, or (b) remove/replace that item. Never retry with
    the same city. Avoid this entirely by calling kapruka_check_delivery with
    `product_id` for each limited item before ordering.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / $defs / CreateOrderInput / properties / currency / description
      Previous value: -"Pricing currency. Supported: LKR, USD, GBP, AUD, CAD, EUR."New value: +"Pricing currency. Supported: LKR, USD, GBP, AUD, EUR."
  2. Changed17 schema fields changed
    • addedInput schema / $defs / CartItem / description
      Added value: +"One cart line — EITHER a catalogue product OR a quoted custom cake.\n\nCatalogue line:   {\"product_id\": \"...\", \"quantity\": 1, \"icing_text\": \"...\"}\nCustom cake line: {\"custom_cake_request_id\": \"...\", \"phone\": \"+9477...\"}\nThe custom cake line is turned into the staff-quoted cake server-side\n(name, picture, price); quantity is always 1 and no price is ever sent."
    • addedInput schema / $defs / CartItem / properties / custom_cake_request_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 80,
      +      "minLength": 6,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "request_id of a custom cake that kapruka_custom_cake_status reports as 'quoted'. Orders the staff-quoted cake (quantity 1). Requires `phone`.",
      +  "title": "Custom Cake Request Id"
      +}
    • changedInput schema / $defs / CartItem / properties / icing_text / description
      Previous value: -"Cake icing text. Silently ignored for non-cake products."New value: +"Cake icing text. Silently ignored for non-cake products. Catalogue lines only."
    • addedInput schema / $defs / CartItem / properties / phone
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 30,
      +      "minLength": 7,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "The customer.phone the custom cake request was made with (custom cake lines only).",
      +  "title": "Phone"
      +}
    • addedInput schema / $defs / CartItem / properties / product_id / anyOf
      Added value: +[
      +  {
      +    "maxLength": 80,
      +    "minLength": 3,
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / $defs / CartItem / properties / product_id / default
      Added value: +null
    • changedInput schema / $defs / CartItem / properties / product_id / description
      Previous value: -"Kapruka product ID (e.g. 'cakeXX000000')."New value: +"Kapruka product ID (e.g. 'cakeXX000000'). Catalogue line."
    • removedInput schema / $defs / CartItem / properties / product_id / maxLength
      Removed value: -80
    • removedInput schema / $defs / CartItem / properties / product_id / minLength
      Removed value: -3
    • removedInput schema / $defs / CartItem / properties / product_id / type
      Removed value: -"string"
    • addedInput schema / $defs / CartItem / properties / quantity / anyOf
      Added value: +[
      +  {
      +    "maximum": 99,
      +    "minimum": 1,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / $defs / CartItem / properties / quantity / default
      Previous value: -1New value: +null
    • changedInput schema / $defs / CartItem / properties / quantity / description
      Previous value: -"Quantity (1–99)."New value: +"Quantity (1–99, default 1). Catalogue lines only."
    • removedInput schema / $defs / CartItem / properties / quantity / maximum
      Removed value: -99
    • removedInput schema / $defs / CartItem / properties / quantity / minimum
      Removed value: -1
    • removedInput schema / $defs / CartItem / properties / quantity / type
      Removed value: -"integer"
    • removedInput schema / $defs / CartItem / required
      Removed value: -[
      -  "product_id"
      -]
  3. Changed1 schema field changed
    • changedInput schema / $defs / Delivery / properties / city / description
      Previous value: -"Must be a Kapruka delivery city — use kapruka_list_delivery_cities to look up valid names."New value: +"Must be a Kapruka delivery city (canonical name from kapruka_list_delivery_cities) that EVERY cart item can reach. The order ships as one shipment, so food / hotel cake / liquor items restrict the whole cart to their city set — verify with kapruka_check_delivery(city, product_id) first; otherwise the order is rejected with city_not_deliverable_for_item."
  4. Changed1 schema field changed
    • changedInput schema / $defs / CartItem / properties / product_id / description
      Previous value: -"Kapruka product ID (e.g. 'cake00ka002034')."New value: +"Kapruka product ID (e.g. 'cakeXX000000')."
  5. Added

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false (write operation), idempotentHint=true, and destructiveHint=false. The description goes far beyond these: it discloses price locking for 60 minutes, free-tier rate limits, idempotency key behavior, and the crucial non-partial-order guarantee on city_not_deliverable_for_item. It also notes potential currency round-trip differences in summary.items_total for custom cakes. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with an opening summary, followed by Args and Returns sections, and bullet points for error codes. It is front-loaded with the core purpose and all additional sentences earn their place by covering behavioral, constraint, or routing details. No fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete given the output schema exists and the schema already documents parameter shapes. It explains the return values (checkout URL, order ref, summary), error codes and their meanings, and the special handling for city_not_deliverable_for_item. An agent has everything needed to call the tool correctly, including when to call companion tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema description coverage is reported as 0%, the tool description adds substantial meaning beyond the schema: it explains the cart line structure (catalogue vs custom cake), phone format requirements, delivery city constraints, gift message length, supported currencies, and response_format options. The schema itself also has detailed descriptions, but the tool description reinforces and adds practical guidance (e.g., never send a price for custom cakes).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool creates a guest-checkout order and returns a click-to-pay link. It specifies the verb ('create'), the resource ('Kapruka order'), and the outcome, and distinguishes itself from siblings by naming the helper tools it coordinates with (kapruka_custom_cake_status, kapruka_list_delivery_cities, kapruka_check_delivery).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use the tool (to place a guest checkout order) and provides critical exclusions: never retry with the same city after city_not_deliverable_for_item, and only place custom cake orders after the customer accepted the quoted total. It also references alternative tools for pre-checks, giving clear routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.