Skip to main content
Glama
manamurah

ManaMurah MCP Server

by manamurah

manamurah-mcp-server

Remote Model Context Protocol (MCP) server for Malaysian PriceCatcher consumer price data. Deployed on Cloudflare Workers. 15 strongly-typed tools for AI agents.

Live endpoint: https://mcp.manamurah.com/mcp (POST, JSON-RPC 2.0)

Data source: data.gov.my PriceCatcher — ~3,800 premises × ~756 items across all 16 Malaysian states/territories, collected daily and published as weekly averages. 100% public government data. No credentials needed anywhere in the stack.


Install

The server speaks streamable HTTP at https://mcp.manamurah.com/mcp. Pick the block for your client:

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json on macOS (or %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "manamurah": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.manamurah.com/mcp"]
    }
  }
}

Claude Desktop only speaks stdio, so the mcp-remote shim is the bridge. Restart the app — you'll see the 15 tools under the 🔌 icon. Ask "harga tembikai di Selangor?" or "what's the cheapest chicken in KL this week?" and Claude will chain search_itemsfind_cheapest automatically.

Claude Code (CLI)

One command, native streamable HTTP — no shim:

claude mcp add manamurah --transport http https://mcp.manamurah.com/mcp

Confirm with claude mcp list. Tools become available the next time you start a Claude Code session. Add --scope user to make it available across every project.

Cursor

User-level (every project): create or edit ~/.cursor/mcp.json. Project-level: <project-root>/.cursor/mcp.json.

{
  "mcpServers": {
    "manamurah": {
      "url": "https://mcp.manamurah.com/mcp"
    }
  }
}

Cursor 0.46+ supports remote MCP via url directly. Reload the window (Cmd-Shift-PDeveloper: Reload Window) and the manamurah row appears under Settings → MCP with all 15 tools listed.

Cline (VS Code extension)

Open Cline's sidebar → ⚙️ → MCP ServersAdd Server → select Remote → paste https://mcp.manamurah.com/mcp → name it manamurah. Cline writes the config to its VS Code global storage itself; no JSON editing needed.

For headless setup, the same JSON shape Claude Desktop uses also works in Cline's cline_mcp_settings.json.

ChatGPT (Custom Connectors)

For ChatGPT Pro / Team / Enterprise: chatgpt.com/connectorsAdd custom connector → MCP server URL https://mcp.manamurah.com/mcp → no auth required (public read-only). After approval the connector shows up in the message-input ⊕ menu.

For OpenAI Apps SDK / programmatic use (the codex_apps.manamurah_* tool family in Codex): the server URL field in the app manifest at platform.openai.com/apps must be exactly https://mcp.manamurah.com/mcpnot https://manamurah.com (which will fail the streamable transport probe with HTTP 403, since that's the consumer site, not an MCP endpoint).

Other MCP clients

Any client that supports streamable-HTTP MCP transport points directly at https://mcp.manamurah.com/mcp. Stdio-only clients shim via mcp-remote using the same recipe as Claude Desktop above.

Quick smoke test from any shell:

curl -sS -X POST https://mcp.manamurah.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'

You should see fourteen tool names — eleven KPDN PriceCatcher tools (weekly cadence) plus three FAMA Panduan Harga Harian tools (daily cadence, three price levels). The richer self-describing manifest (full input schemas + versioning policy) is also a single GET away.

Related MCP server: Weather MCP MY

Tools

All 15 tools are read-only, public, and capped on response size to keep LLM contexts compact. Every tool carries a detailed description

  • JSON-Schema input so the LLM picks the right one without guessing.

KPDN PriceCatcher (weekly averages)

Retail prices only. ~3,800 premises × ~756 items, collected daily and published as weekly averages from the data.gov.my PriceCatcher dataset.

Tool

Purpose

search_items

Find items by name in Malay / English / Chinese / Tamil

find_cheapest

Up to 10 cheapest premises for one item this week

price_history

Weekly price trend at national/state/district/chain/urban

nearby_premises

Premises within a geographic radius of a coordinate

compare_prices

One item's price across national + state + district + more

list_chains

Directory of retail chains + premise counts + coverage

price_change

Delta between current week and 1 / 3 / 6 / 12 months ago

top_movers

Biggest weekly risers + fallers

category_trends

Per-category movement over a window

basket_watch

Total cost for a 1–20 item basket over time

region_gap

Semenanjung vs Borneo top-N price gap, both directions

FAMA daily prices (Panduan Harga Harian)

Three price levels — RUNCIT (retail), BORONG (wholesale), LADANG (farm-gate) — tracked daily and independently. ~46 items (fresh produce, eggs, poultry). FAMA's catalogue is independent of PriceCatcher: item_id here is FAMA's own 1..46, not the KPDN item_code.

Tool

Purpose

fama_price_history

Daily series for one item at chosen level + geographic grain

fama_margin

LADANG → BORONG → RUNCIT value-chain spread per day

fama_top_movers

Daily movers per level, anchored on latest index date

fama_margin and fama_top_movers reject grain='daerah' because LADANG/BORONG coverage at daerah grain is too sparse for an honest cut. fama_price_history accepts daerah for retail-only callers.

All tools require zero setup beyond the MCP config above. No API keys. No rate limiting on the client side (upstream has a 12h KV edge cache so repeat queries are essentially free).

Example conversation

You: Berapa harga tembikai merah tanpa biji di Selangor minggu ini?

Claude (calls search_items(query="tembikai") → gets item_code 21 → calls find_cheapest(item_code=21, state="Selangor")):

Tembikai merah tanpa biji di Selangor untuk minggu 2026-04-20: hanya ada 1 kedai yang melaporkan data PriceCatcher — Jaya Grocer D'Pulze Cyberjaya di daerah Sepang pada RM 5.20/kg. Data lain di KL menunjukkan NSK Seputeh/Cheras/Kepong menjual tembikai serupa pada RM 1.69/kg — mungkin berbaloi keluar PJ/KL jika anda di Selangor Selatan.

The structured response the LLM worked from:

{
  "item_code": 21,
  "item_name": "TEMBIKAI MERAH TANPA BIJI",
  "weekdate": "2026-04-20",
  "results": [
    {
      "weekdate": "2026-04-20",
      "price": 5.20,
      "premise_name": "JAYA GROCER D`PULZE CYBERJAYA",
      "chain": "JAYA GROCER",
      "chain_type": "SUPERMARKET",
      "state": "Selangor",
      "district": "Sepang"
    }
  ],
  "scope": { "state": "Selangor", "district": null, "chain": null, "chain_type": null },
  "status": "ok",
  "reason": null,
  "warnings": []
}

Architecture

 Claude Desktop ─ stdio ─ mcp-remote ─ HTTPS ─ mcp.manamurah.com
                                                    │
                                               (Cloudflare Worker, this repo)
                                                    │
                                                  fetch
                                                    ▼
                                        manamurah.com/api/v2/mcp/*
                                                    │
                                               (SvelteKit site +
                                                Cloudflare KV edge cache,
                                                12h TTL)
                                                    │
                                                    ▼
                                            public price data

This Worker is a thin protocol shim — it speaks MCP JSON-RPC on one side and standard fetch() on the other. No business logic, no credentials, no database binding. Every tool call goes to exactly one upstream /api/v2/mcp/<tool> endpoint and passes the JSON response through.

Keeping the shim thin means:

  • The ~400 lines here are almost all tool-description JSON.

  • Query/caching/index logic lives upstream where it's co-located with the data layer.

  • Updating a tool's behaviour rarely requires a Worker redeploy.

Self-host / fork

git clone https://github.com/manamurah/mcp-server
cd mcp-server
pnpm install

# Local dev — hot-reloads on src/ changes, binds to 127.0.0.1:8787
pnpm dev

# Exercise it:
curl -sS -X POST http://127.0.0.1:8787/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'

# Deploy to your own Cloudflare account:
pnpm deploy

To point at a staging copy of the upstream (useful when manamurah_20240322 ships new /api/v2/mcp/* endpoints), override the base URL in wrangler.toml:

[vars]
MANAMURAH_API_BASE = "https://staging.manamurah.com"

Protocol notes

  • Transport: HTTP POST at /mcp, JSON-RPC 2.0. CORS-open so browser-based MCP clients work without a proxy.

  • Methods supported: initialize, tools/list, tools/call, prompts/list, prompts/get, resources/list, resources/read, resources/templates/list, completion/complete, ping.

  • Tool response shape: MCP content: [{ type: "text", text: ... }] blocks with the raw JSON payload also attached as structuredContent for clients that prefer it.

  • Error handling: business-level issues (invalid args, no data for this week) come back as { "status": "no_data", "reason": ... } at HTTP 200 so the LLM can narrate them. Only transport/infra failures raise JSON-RPC errors.

  • Upstream errors: 5xx on /api/v2/mcp/* bubbles up as JSON-RPC code: -32603 with the upstream status in data. 4xx passes through unchanged (client validation error already shaped as a JSON envelope on the upstream side).

  • manamurah-mcp-2026 — Python stdio MCP server covering the same 15 tools. Use this instead if you want a local-only MCP binary (no Cloudflare, no Worker hop).

  • manamurah_20240322 — the SvelteKit site at manamurah.com. Hosts both the public website and the /api/v2/mcp/* proxy endpoints this Worker calls.

  • manamurah-data-2026 — the Python ETL that populates the indices behind everything else. Nightly pipeline, data.gov.my PriceCatcher source of truth.

License

MIT. See LICENSE.

A
license - permissive license
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/manamurah/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server