Lakpura® MCP Server REST API What is MCP?

MCP Server

A Model Context Protocol server that lets AI agents search and book Lakpura® tours, transfers and stays — ending in a hosted Stripe checkout URL the customer pays.

Endpoint
https://mcp.lakpura.com
Transport
Streamable HTTP — JSON-RPC 2.0 over POST (single JSON response; no SSE)
Server identity
com.lakpura/mcp v1.0.1
Protocol version
2025-06-18
Auth
Open by default (see below)
Content-Type
application/json on request and response
This documents the MCP surface only. The Lakpura® REST API is a separate, JWT-authenticated, path-per-resource contract for the mobile app; the MCP server is a single JSON-RPC endpoint exposing a small public booking toolset for autonomous agents. The two are independent contracts on their own hostnames.

Authentication

Open by default — no credentials required. search_* and get_service return public catalogue data, and start_booking only returns a hosted Stripe URL (no payment credentials cross the wire).

The operator can require a bearer token by setting MCP_BEARER_TOKEN server-side; when set, every request must send Authorization: Bearer <token> or receive 401 (JSON-RPC error -32001).

Connecting (JSON-RPC methods)

Standard MCP lifecycle. All real calls are POST. A GET to the endpoint with Accept: application/json returns a plain server descriptor (name, version, protocol, transport); a browser GET returns this page.

MethodPurpose
initializeHandshake — negotiates protocol version, returns serverInfo, capabilities and usage instructions.
notifications/initializedClient → server notification after init. No response (202).
tools/listReturns the tool catalogue with inputSchema for each tool.
tools/callInvokes a tool by name with arguments. Result is content: [{ type:"text", text:"<JSON>" }] plus an isError flag.
pingLiveness check — returns {}.

JSON-RPC batches (an array of request objects) are supported. Requests without an id are notifications and get no response.

Tools

search_stays

Search Lakpura accommodation (hotels, villas, lodges) by name or city. Returns matching stays with their public page URL, city, country and star rating. Use get_service with a returned slug for room details and price.

ParamTypeDescription
queryrequiredstringHotel/villa name or city (e.g. "Galle", "Cinnamon", "Ella tree house").
limitoptionalintegerMax results (default 12).

search_tours

Search Lakpura tours, day-trips and experiences by keyword. Returns each match with a slug, title, rating and public page URL. Call get_service with a slug to see bookable options and price, then start_booking.

ParamTypeDescription
queryoptionalstringKeyword(s) matched against the tour title (e.g. "whale watching", "sigiriya", "safari").
kindoptionalenumall · multi_day · single_day. Default all.
pageoptionalintegerPage number (default 1).
per_pageoptionalintegerResults per page (default 20).

get_service

Get full details of one tour/experience by slug: title, description, bookable options (each with a price and option_id) and whether it can be booked via start_booking.

ParamTypeDescription
slugrequiredstringThe service slug from search_tours (the last path segment of /products/{slug}).

start_booking

Create a booking and get a secure Stripe checkout URL for the customer to pay. Price is calculated server-side and returned with the checkout_url; payment confirms the booking.

product_type = tour   product_type = transfer

ParamTypeDescription
product_typerequiredenumtour · transfer — what is being booked.
lead_first_namerequiredstringCustomer first name.
lead_surnamerequiredstringCustomer surname.
lead_emailrequiredstringCustomer email (booking confirmation is sent here).
lead_phoneoptionalstringCustomer phone (E.164 preferred).
paxoptionalintegerNumber of guests/passengers (default 1).
slugoptionalstringtour: service slug from search_tours/get_service.
option_idoptionalstringtour: chosen option_id from get_service (omit for the "from" price).
selected_dateoptionalstringtour: travel date, YYYY-MM-DD (today or later).
selected_start_timeoptionalstringtour: start time, e.g. "09:00".
pickup_textoptionalstringtour: pickup location / hotel.
fromoptionalstringtransfer: pickup location (airport / city / hotel).
tooptionalstringtransfer: drop-off location.
vehicleoptionalstringtransfer: vehicle class (default "Standard Car").
categoryoptionalstringtransfer: e.g. "Arrival Transfers", "Departure Transfers" (default Arrival).
pickup_atoptionalstringtransfer: pickup datetime (free text or ISO).
airlineoptionalstringtransfer: airline (airport transfers).
flight_numberoptionalstringtransfer: flight number.
notesoptionalstringtransfer: free-text notes.

Booking flow

Tours: search_toursget_service (pick an option_id) → start_booking → open the returned checkout_url.

Transfers: start_booking with product_type="transfer", from/to and lead details → open checkout_url.

Stays: search_staysget_service for room details. (Stay booking is a page handoff, not an in-protocol start_booking today.)

Example

Handshake, then list tools:

# initialize
curl -s https://mcp.lakpura.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-06-18",
                 "clientInfo":{"name":"my-agent","version":"1.0"}}}'

# list tools
curl -s https://mcp.lakpura.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

Call a tool (search_tours):

curl -s https://mcp.lakpura.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"search_tours",
                 "arguments":{"query":"whale watching"}}}'

Errors

Transport failures use JSON-RPC error objects; tool-level failures come back as a normal result with isError: true and an { "error": "…" } payload in the text content.

CodeMeaning
-32700Parse error (malformed JSON)
-32600Invalid Request
-32601Method not found
-32602Invalid params / unknown tool
-32001Auth required / invalid bearer token (401)
-32603Internal error / service unavailable