Skip to main content

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)
"

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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

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