Skip to main content

MCP server for 591 rental listings

Project description

mcp-591

An MCP server that lets AI assistants search property listings on 591.com.tw, Taiwan's largest real estate platform.

Disclaimer: This project scrapes data from an undocumented API. It is intended for personal research only. Do not use it for bulk or high-frequency requests.

Also available in: 繁體中文

Example

User: 幫我搜尋青埔周邊 10 年內的大樓,總價控制在 1200 萬左右

Claude calls search_sale with the inferred parameters:

{
  "region": "桃園市",
  "section": "中壢區",
  "shape": "電梯大樓",
  "age": "5_10",
  "price_str": "1000_1400",
  "keywords": "青埔"
}

Claude: 青埔周邊 1,0001,400 萬、10 年內電梯大樓,共找到 5年內 135 筆、510年 146 筆,以下整理 CP 值較高的物件:...

Requirements

  • Python 3.14+
  • uv

Installation

git clone <repo>
cd mcp-591
uv sync

Usage

As an MCP Server (Claude Desktop / Claude Code)

The repo ships a .mcp.json that Claude Code picks up automatically:

{
  "mcpServers": {
    "591": {
      "command": "uv",
      "args": ["run", "mcp-591"],
      "cwd": "${PWD}"
    }
  }
}

Four tools are exposed:

search_sale — Search for sale listings

Parameter Type Description
region str (required) County/city name, e.g. 桃園市
section str District, e.g. 中壢區. Omit to search the whole county.
kind str Property type, default 住宅. Options: 住宅 / 店面 / 辦公 / 廠房 / 車位 / 套房 / 土地 / 住辦
shape str Building type: 公寓 / 電梯大樓 / 透天厝 / 別墅
pattern str Room count: 1房 / 2房 / 3房 / 4房 / 5房以上
toilet str Bathroom count: 1衛 / 2衛 / 3衛 / 4衛 / 5衛以上
area str Floor area range (坪): 10_20 / 20_30 / 30_40 / 40_50 / 50_60 / 60_100 / 100_150 / 150_200
age str Building age: _5 (under 5 yrs) / 5_10 / 10_20 / 20_30 / 30_40 / 40_ (40+ yrs)
price_str str Price range in 萬 NTD, e.g. 1000_1500 or 1000_1250,1250_1500
keywords str Free-text search, e.g. 捷運 (MRT)
page_size int Results per page, max 30 (default 30)
first_row int Pagination offset (default 0)

get_sale_detail — Fetch full listing details

Parameter Type Description
post_id str Listing ID from a search_sale result

Returns: floor area breakdown (main area / common-area ratio), floor, building age, nearby transit, parking, fitment, mortgage estimate, contact info, and description.

search_rent — Search for rental listings

Parameter Type Description
region str (required) County/city name, e.g. 桃園市
section str District, e.g. 中壢區. Omit to search the whole county.
kind str Room type: 整層住家 / 獨立套房 / 分租套房 / 雅房 / 車位
shape str Building type: 公寓 / 電梯大樓 / 透天厝 / 別墅
pattern str Room count: 1房 / 2房 / 3房 / 4房 / 5房以上
price_str str Monthly rent range in NTD, e.g. 10000_20000
keywords str Free-text search, e.g. 捷運 (MRT)
first_row int Pagination offset (default 0). Use next_first_row from the previous response.

get_rent_detail — Fetch full rental listing details

Parameter Type Description
post_id str Listing ID from a search_rent result

Returns: price, deposit, floor area, floor, building type, layout, address with lat/lng, lease period, move-in date, pet/cooking/gender policies, facilities, contact info, and description.

Running the client directly (debugging)

# Search 桃園市中壢區
uv run python -m mcp_591.client 桃園市 中壢區

# With filters: shape pattern toilet area age
uv run python -m mcp_591.client 桃園市 中壢區 電梯大樓 3房 2衛 30_40 _5

Argument order: <county> [district] [shape,...] [pattern,...] [toilet,...] [area] [age]. Pass an empty string "" to skip an intermediate argument.

Development & Testing

# Install with dev dependencies
uv sync --dev

# Unit tests (no network, uses fixtures)
uv run pytest

# Integration tests (hits the real 591 API)
uv run pytest -m integration

Test layout

tests/
├── fixtures/
│   ├── search_sale.json   # Captured sale search response
│   ├── sale_detail.json   # Captured sale detail response
│   ├── search_rent.json   # Captured rent search response
│   └── rent_detail.json   # Captured rent detail response
├── test_server.py         # Unit tests: filtering and tool logic
└── test_integration.py    # Integration tests (skipped by default)

To refresh fixtures (requires network):

uv run python -c "
import json
from mcp_591.client import Client591
c = Client591()
json.dump(c.search_sale(region_id=6, section_ids=[67], kind=9, page_size=5),
          open('tests/fixtures/search_sale.json', 'w'), ensure_ascii=False, indent=2)
json.dump(c.get_sale_detail(19708683),
          open('tests/fixtures/sale_detail.json', 'w'), ensure_ascii=False, indent=2)
json.dump(c.search_rent(region_id=6, section_ids=[67], kind=1),
          open('tests/fixtures/search_rent.json', 'w'), ensure_ascii=False, indent=2)
json.dump(c.get_rent_detail(21103645),
          open('tests/fixtures/rent_detail.json', 'w'), ensure_ascii=False, indent=2)
"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_591-0.1.1.tar.gz (90.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_591-0.1.1-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file mcp_591-0.1.1.tar.gz.

File metadata

  • Download URL: mcp_591-0.1.1.tar.gz
  • Upload date:
  • Size: 90.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_591-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f326ad794c88f63cf29cba0e07f12ad56f5aff0485c0df8340f16f767947fc84
MD5 3f151b42bfdd67ae2963a7def36e6362
BLAKE2b-256 9dbcb70daaf4500cd183d48d9036b54e61136ffc77b1dba3f9e7d49be258faba

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_591-0.1.1.tar.gz:

Publisher: publish.yml on asgard-ai-platform/mcp-591

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_591-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_591-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_591-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 102fb0541436a05117907627f5ffde03990edb3cad96da89a65622b2a7fc9693
MD5 ce307e9d908ee3aa4d8c6f6f12a49950
BLAKE2b-256 f8817667ba8c4e12f3b0e233b0c5cd9147d162a6ee9fab28dcdfd43f7fa7ee7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_591-0.1.1-py3-none-any.whl:

Publisher: publish.yml on asgard-ai-platform/mcp-591

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page