ManaMurah MCP Server
Deployed on Cloudflare Workers for global performance, providing a serverless infrastructure for the MCP server with built-in rate limiting and abuse protection.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ManaMurah MCP Serverwhat are the current prices for cooking oil in Selangor?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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_items → find_cheapest automatically.
Claude Code (CLI)
One command, native streamable HTTP — no shim:
claude mcp add manamurah --transport http https://mcp.manamurah.com/mcpConfirm 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-P → Developer: Reload Window) and the
manamurah row appears under Settings → MCP with all 15 tools
listed.
Cline (VS Code extension)
Open Cline's sidebar → ⚙️ → MCP Servers → Add 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/connectors →
Add 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/mcp — not 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 |
| Find items by name in Malay / English / Chinese / Tamil |
| Up to 10 cheapest premises for one item this week |
| Weekly price trend at national/state/district/chain/urban |
| Premises within a geographic radius of a coordinate |
| One item's price across national + state + district + more |
| Directory of retail chains + premise counts + coverage |
| Delta between current week and 1 / 3 / 6 / 12 months ago |
| Biggest weekly risers + fallers |
| Per-category movement over a window |
| Total cost for a 1–20 item basket over time |
| 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 |
| Daily series for one item at chosen level + geographic grain |
| LADANG → BORONG → RUNCIT value-chain spread per day |
| 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 → callsfind_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 dataThis 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 deployTo 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 asstructuredContentfor 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-RPCcode: -32603with the upstream status indata. 4xx passes through unchanged (client validation error already shaped as a JSON envelope on the upstream side).
Related
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.
This server cannot be installed
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