propertyguru-mcp

propertyguru-mcp

Unofficial MCP server that exposes PropertyGuru Singapore & Malaysia property listing search as MCP tools, returning detailed listing data without an API key.

Category
访问服务器

README

propertyguru-mcp

Python 3.10+ License: MIT MCP Tests

Unofficial MCP (Model Context Protocol) server that exposes PropertyGuru Singapore & Malaysia listing search as MCP tools. No API key. No subscription. One HTTP request per query.


⚠️ Disclaimer

This project is not affiliated with, endorsed by, or connected to PropertyGuru Group in any way. It is an unofficial, community-maintained tool built for personal research and educational purposes.

  • PropertyGuru® and the PropertyGuru logo are trademarks of PropertyGuru Group.
  • This tool scrapes publicly available HTML that PropertyGuru renders server-side. Use of this tool may violate PropertyGuru's Terms of Service. Use at your own risk.
  • No warranty. The authors are not responsible for any consequences of using this tool.
  • If you are PropertyGuru and want this taken down, please open an issue and I will respond promptly.

What data does it provide?

Each search_listings call returns up to 25 listings (one page) with the complete 48-field listingData as rendered by PropertyGuru itself. Highlights:

Category Fields
Price price.value, price.pretty ("S$ 3,499,999"), price.type.text (Negotiable / Offers Welcome)
Area area.localeStringValue ("1,873 sqft"), floorArea
PSF pricePerArea.localeStringValue ("S$ 1,868.66 psf")
Layout bedrooms, bathrooms, property.subTypeText (Condominium / HDB / Apartment / Landed / Commercial)
Tenure / Age Freehold vs 99-year Leasehold; "Built: 2010"
Address fullAddress ("29 Angullia Park"), shortAddress ("Orchard / River Valley, D09-10")
Public transit mrt.nearbyText ("7 min (570 m) from NS22 Orchard MRT Station")
Photos mediaCarousel.previewMedia.images.items[] (15-30 hi-res URLs per listing), floorPlans.items[]
Agent agent.name, agent.license (e.g. R057754I), agent.profileUrl, agent.description, agency.name
Status isVerified, isOfficialListing, isDeveloperListing, isPrioritized
Posted postedOn.text, postedOn.unix
Highlights highlights.items (project selling points)
URL Direct link to the listing detail page

No field pruning. Server returns the raw listingData structure — the example below is the exact JSON a caller receives.


Demo

Real output of search_listings(region="sg", listing_type="rent", freetext="Orchard", bedrooms_min=3, price_min=3000000, price_max=5000000):

{
  "count": 25,
  "listings": [
    {
      "id": 25472440,
      "price": { "value": 3499999, "pretty": "S$ 3,499,999", "type": { "text": "Negotiable" } },
      "pricePerArea": { "localeStringValue": "S$ 1,868.66 psf" },
      "area": { "localeStringValue": "1,873 sqft" },
      "bedrooms": 3, "bathrooms": 3,
      "localizedTitle": "Orchard Scotts",
      "fullAddress": "251 Orchard Road",
      "shortAddress": "Orchard / River Valley (D09-10)",
      "mrt": { "nearbyText": "10 min (840 m) from NS21 Newton MRT Station" },
      "mediaItems": [{ "icon": "images", "text": "18", "mediaType": "images" }],
      "agent": { "name": "Edwin Phua", "license": "R057754I" },
      "agency": { "name": "HUTTONS ASIA PTE. LTD." },
      "url": "https://www.propertyguru.com.sg/listing/for-sale-orchard-scotts-25472440",
      "postedOn": { "text": "11 Aug 2026", "unix": 1786419975 }
    },
    ...
  ]
}

How it works

PropertyGuru is a Next.js SSR site. When you visit a listing-search URL, the server embeds the complete result set as JSON at a well-known DOM id:

<script id="__NEXT_DATA__" type="application/json">{
  "props": { "pageProps": { "pageData": { "data": {
    "listingsData": [ { "listingData": { ... }, ... }, ... ]
  } } } }
}</script>

This MCP server:

  1. Builds a filter URL using the same minPrice/maxPrice/bedrooms[]/freetext param spelling PropertyGuru's own frontend uses.
  2. Fetches the HTML page with a plain browser User-Agent.
  3. Parses __NEXT_DATA__ (regex → json.loads).
  4. Returns the raw listingData array as JSON to the caller.

Why no third-party API key: because we're not using PropertyGuru's paid partner APIs — we're reading the same HTML your browser would receive.


Tools

search_listings

The primary tool. Returns a page of full listings.

Param Type Required Default Description
region sg | my ✅ sg Singapore or Malaysia
listing_type sale | rent ✅ sale —
freetext string — — Free text: "Orchard", "Mont Kiara", "Tampines", "Orchard Scotts" (specific condo)
property_type string — — CONDO, HDB, LANDED, APARTMENT, COMMERCIAL
bedrooms_min int — — When bedrooms_min == bedrooms_max, treated as exact match
bedrooms_max int — — Studio = 0
price_min int — — Local currency (SGD or MYR)
price_max int — —
sort enum — — price_asc, price_desc, date, psf
limit int ≤ 40 — 25 Single page cap

get_listing_count

Cheap probe returning only the count for a search (use to size a query before fetching).


Installation

# Clone and install
git clone https://github.com/kkukoo/propertyguru-mcp.git
cd propertyguru-mcp

# Option A: uv (recommended)
uv venv && uv pip install -e .

# Option B: plain pip
python -m venv .venv && ./.venv/bin/pip install -e .

# Run tests
python -m pytest tests/ -v

After install, the MCP server is available three ways (all equivalent):

# 1. Console script
.venv/bin/propertyguru-mcp

# 2. Module invocation
.venv/bin/python -m propertyguru_mcp

# 3. Direct path (no install needed if you prefer running from source)
python src/propertyguru_mcp/server.py

The server talks MCP over stdio (the default transport for MCP clients). It does not listen on any network port.


Hooking up to your MCP client

Below are working config snippets. Replace /path/to/propertyguru-mcp and the python interpreter with whatever you used in the install step.

Hermes Agent — ~/.hermes/config.yaml

mcp_servers:
  propertyguru:
    command: /path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp
    args: []
    timeout: 60
    connect_timeout: 30

Reload via hermes gateway restart (from a shell outside Hermes) or /restart from inside the gateway chat.

Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "propertyguru": {
      "command": "/path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp",
      "args": []
    }
  }
}

Restart Claude Desktop after editing.

Cursor — ~/.cursor/mcp.json

{
  "mcpServers": {
    "propertyguru": {
      "command": "/path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp",
      "args": []
    }
  }
}

Cline (VS Code extension)

In Cline Settings → MCP, add:

{
  "propertyguru": {
    "command": "/path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp",
    "args": []
  }
}

Continue.dev

Edit ~/.continue/config.json:

{
  "experimental": {
    "modelContextProtocolServers": [{
      "name": "propertyguru",
      "transport": {
        "type": "stdio",
        "command": "/path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp",
        "args": []
      }
    }]
  }
}

Any OpenAI Agents SDK-compatible client

The standard MCP stdio pattern works:

from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    name="propertyguru",
    params={
        "command": "/path/to/propertyguru-mcp/.venv/bin/propertyguru-mcp",
        "args": [],
    },
) as server:
    tools = await server.list_tools()

Known limitations

  • Single-page responses (25 listings). PropertyGuru's &page=N query-string is unreliable from non-browser User-Agents (Cloudflare blocks intermittently). Path-style /{region}/property-for-sale/2 works but is untested in the server. If you need > 25 listings, run multiple freetexts / districts and merge client-side.
  • Cloudflare. If PropertyGuru starts challenging this server's User-Agent or your IP, you'll get HTTP 403 errors. Workarounds: slow down request rate; route via a residential proxy; switch to a browser-based toolset (e.g. Hermes browser_exec).
  • Field drift. PropertyGuru can reshape __NEXT_DATA__ any time. When it does, search_propertyguru will raise and you'll need to re-trace the path (look at the live page's __NEXT_DATA__ in browser DevTools).
  • Singapore + Malaysia only. PropertyGuru has other regional sites (propertyguru.co.id, .co.th) — PRs welcome.
  • No autocomplete endpoint. There's a separate RapidAPI endpoint that does location autocomplete; if you want that here, it's a clean addition (file an issue or open a PR).
  • No detail endpoint. To get full listing descriptions / floor plans, you need one extra fetch per listing — not implemented yet.

Roadmap

  • [ ] Stable multi-page support (handle Cloudflare + path-style /{n} pagination)
  • [ ] autocomplete_locations(query) — return objectId / district / MRT proximity
  • [ ] get_listing_detail(listing_url) — full description, all photos, floor plans
  • [ ] Built-in rate limiter (configurable requests/min) to stay polite to PropertyGuru
  • [ ] Optional thin server-side projection (e.g. fields=summary) to save caller tokens
  • [ ] Indonesia / Thailand region support

Contributing

See CONTRIBUTING.md. PRs welcome — especially for:

  • New regions (Indonesia/Thailand)
  • New endpoints (autocomplete, detail, project pages)
  • Tests for additional URL parameter combinations
  • Better Cloudflare resilience
  • Example usage for other MCP clients (Windsurf, Codex, OpenClaw, etc.)

License

MIT — see LICENSE.


Acknowledgements

Built with modelcontextprotocol/python-sdk. Inspired by the wider community's shared frustration that real-estate data is artificially locked down by a handful of aggregators.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选