For agents & developers

Connect to the
laparku MCP server.

laparku-menus exposes an MCP (Model Context Protocol) server over Streamable HTTP, so any MCP client โ€” Claude Code, Claude Desktop, an agent you write โ€” can search Brunei's crowdsourced food dataset and file menu submissions.

The endpoint

One URL, POST-only, JSON-RPC over Streamable HTTP:

https://laparku-menus.bbdl.workers.dev/mcp

Requests must send Accept: application/json, text/event-stream and Content-Type: application/json. The server is stateless โ€” no session cookies, no resumable streams. Each request creates and tears down a session inside one response.

Quick health check โ€” this initialize handshake should return a JSON-RPC result naming the server:
curl -s -X POST https://laparku-menus.bbdl.workers.dev/mcp \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

Client configs

1Claude Code

From a terminal, register it as an HTTP server:

claude mcp add --transport http laparku-menus \
  https://laparku-menus.bbdl.workers.dev/mcp

2Claude Desktop / other MCP clients

For clients that only launch stdio servers locally, point them at a stdio-to-HTTP bridge such as mcp-remote and give it the endpoint URL:

{
  "mcpServers": {
    "laparku-menus": {
      "command": "npx",
      "args": ["mcp-remote", "https://laparku-menus.bbdl.workers.dev/mcp"]
    }
  }
}

3From your own code

Use any MCP client SDK in Streamable-HTTP mode. With the official TypeScript SDK:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(
  new URL("https://laparku-menus.bbdl.workers.dev/mcp"),
));
const { tools } = await client.listTools();
const result = await client.callTool({
  name: "search_items",
  arguments: { query: "nasi katok", filters: { area: "Brunei-Muara" } },
});

Available tools

Read tools are public โ€” no authentication needed. Write tools take your API key as a tool argument called api_key.

ToolAuthWhat it does
search_items public Full-text search over published items and venues. Args: query (string, required), filters โ€” venue_type, item_type (dish|product), area, halal, tag, max_price (BND).
list_venues public List published venues. Args: filters โ€” type, area, halal, q.
get_venue_items public The current published menu of one venue. Args: venue_id (required).
submit_menu api_key File a submission for human review โ€” nothing publishes without approval. Args: api_key, payload with source_type (menu_pdf, menu_photo, product_photo, barcode, url, manual_entry), provenance (where the data came from โ€” required), optional contact, files (base64 jpeg/png/webp/pdf) or items (manual_entry only).
get_submission_status api_key Check one of your own submissions โ€” a key only sees what it filed. Args: id (from submit_menu), api_key.

Valid enum values โ€” area: Brunei-Muara, Tutong, Belait, Temburong. venue_type: restaurant, stall, supermarket, grocer, convenience. halal: halal-certified, muslim-owned, non-halal, unknown, n-a.

Getting an API key

Keys belong to a submitter account, which is how submissions and reputation are attributed:

  1. Open the menu app and sign in โ€” magic link, no password.
  2. Create a key via the auth API while signed in:
    curl -s -X POST https://laparku-menus.bbdl.workers.dev/api/auth/api-key/create \
      -H 'Content-Type: application/json' \
      -H 'Cookie: <your session cookie>' \
      -d '{"name":"my-agent"}'
  3. Pass the returned key as the api_key argument to submit_menu and get_submission_status. Keep it secret โ€” it identifies you.
The key travels inside tool arguments, not headers โ€” that keeps auth out of connection config but means MCP clients may log it in traces. Treat agent logs accordingly.

Build something on it

The dataset is open and growing โ€” a diet coach that plans hawker meals, a grocery price tracker, a meal-planner that knows what's nearby. If your app needs a tool that doesn't exist yet, open an issue.