For AI developers
Order food with an AI assistant
Restaurants hosted on lokal.business are orderable by any MCP-compatible client — ChatGPT, Claude, or your own agent. Structured tools, live prices, a real cart, an explicit confirmation step, and a safe test mode. No HTML scraping.
Connect
| Endpoint | https://lokal.business/api/mcp/ordering |
| Transport | Streamable HTTP (JSON-RPC 2.0). SSE at /api/mcp/ordering/sse. |
| SDK | Official @modelcontextprotocol/sdk — protocol 2025-06-18. |
| Auth | None for menu, cart, and test orders. Live orders need a Bearer token (contact us). |
Client configuration
{
"mcpServers": {
"lokal-ordering": {
"type": "streamable-http",
"url": "https://lokal.business/api/mcp/ordering"
}
}
}In Claude Desktop / Code add it as a remote MCP server. In the OpenAI Agents SDK, register it as a Streamable-HTTP MCP tool provider.
The 18 tools
search_restaurants | Find restaurants that take online orders. |
search_businesses | Find any local business — not just restaurants — by need, city, or payment and fulfilment options. |
get_restaurant | Hours, open/closed now, fulfilment + payment options. |
get_menu | Live menu: categories, item_ids, prices, availability, add-ons. |
search_menu_items | Natural-language item search ('chicken momo') → item_ids + confidence. |
get_menu_item | Everything about one item by item_id. |
create_cart | Open a server-side cart (test-mode by default). |
add_cart_item | Add an item by item_id — the server prices it. |
update_cart_item | Change quantity / add-ons / instructions. |
remove_cart_item | Remove a line. |
get_cart | The current server-validated cart + totals. |
set_fulfillment | Pickup or delivery, requested time, address. |
set_customer | Name + phone (responses only echo a masked phone). |
get_payment_methods | What the restaurant actually accepts. |
validate_order | Final check → confirmation_summary + confirmation_token. Does NOT place. |
place_order | Place it — needs the token + explicit customer yes. Idempotent. |
get_order_status | Status of an order. |
cancel_order | Cancel while still new. |
Read-only resources: lokal://restaurants/{slug}, …/menu, …/payment-methods, …/orders/{orderId}.
Example ordering workflow
1. search_restaurants { "query": "kathmandu" }
2. search_menu_items { "restaurant_slug": "kathmandu-curry-and-bar",
"query": "one plate of chicken momo" }
→ pick the item_id (this menu has TWO "Chicken Momo" — ask the
customer which if more than one matches; never guess by name)
3. create_cart { "restaurant_slug": "kathmandu-curry-and-bar",
"fulfillment_type": "pickup" } → cart_id
4. add_cart_item { "cart_id": "...", "item_id": "...", "quantity": 1 }
5. set_fulfillment { "cart_id": "...", "fulfillment_type": "pickup",
"requested_time": "ASAP" }
6. set_customer { "cart_id": "...", "name": "...", "phone": "..." }
7. validate_order { "cart_id": "...", "payment_method": "cash_pickup" }
→ read confirmation_summary to the customer, keep confirmation_token
8. ── ASK THE CUSTOMER TO CONFIRM. Only if they say yes: ──
9. place_order { "cart_id": "...", "payment_method": "cash_pickup",
"confirmation_token": "...",
"idempotency_key": "unique-per-order" }
→ order_id, total, tracking_url
10. get_order_status { "order_id": "...", "restaurant_slug": "..." }Confirmation & safety
- Never place an order straight from the first message. Build the cart,
validate_order, read the summary, get an explicit yes, thenplace_order. place_orderrequires aconfirmation_tokenfromvalidate_order. The token is bound to the exact cart and total — it stops working if anything changes.- Pass a stable
idempotency_keyso a retry can never create a second order. - The server prices everything. Prices you send are ignored.
- Responses only ever echo a masked phone (e.g.
•••• 0100).
Test mode
Every order is a test order by default. Test orders are flagged is_test_order: true, prefixed [TEST], noted “do not prepare,” and send no SMS and no kitchen ticket. Cash pickup stays selectable; no real payment is ever taken.
Demo restaurant: Kathmandu Curry & Bar — kathmandu-curry-and-bar. Its stored order metadata carries source: "mcp", ai_client, session_id and idempotency_key so test orders are easy to find and remove. Live ordering (mode "live") requires an authorized token.
Discovery
Machine-readable manifest: /.well-known/mcp. Also linked from /llms.txt. Restaurant directory + product feed: /api/feeds/restaurants.