dld-mcp 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dld_mcp-0.2.0/.gitignore +29 -0
- dld_mcp-0.2.0/LICENSE +21 -0
- dld_mcp-0.2.0/PKG-INFO +98 -0
- dld_mcp-0.2.0/README.md +77 -0
- dld_mcp-0.2.0/pyproject.toml +41 -0
- dld_mcp-0.2.0/src/dld_mcp/__init__.py +5 -0
- dld_mcp-0.2.0/src/dld_mcp/server.py +89 -0
- dld_mcp-0.2.0/uv.lock +752 -0
dld_mcp-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
|
|
8
|
+
# Virtual environments
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
|
|
12
|
+
# IDE/Editor
|
|
13
|
+
.idea/
|
|
14
|
+
.vscode/
|
|
15
|
+
*.swp
|
|
16
|
+
|
|
17
|
+
# Local config
|
|
18
|
+
.env
|
|
19
|
+
.env.local
|
|
20
|
+
|
|
21
|
+
# Claude Code
|
|
22
|
+
.claude/
|
|
23
|
+
|
|
24
|
+
# OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
27
|
+
|
|
28
|
+
# Internal docs (not for public)
|
|
29
|
+
PLAN.md
|
dld_mcp-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 OfferBrief
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dld_mcp-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dld-mcp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: MCP server for Dubai real estate - DLD transactions and Ejari rentals
|
|
5
|
+
Project-URL: Homepage, https://offerbrief.com
|
|
6
|
+
Project-URL: Repository, https://github.com/level09/dld-mcp
|
|
7
|
+
Author-email: OfferBrief <hello@offerbrief.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: dld,dubai,ejari,mcp,property,real-estate,rentals,uae
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
19
|
+
Requires-Dist: mcp>=1.0.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# DLD MCP Server
|
|
23
|
+
|
|
24
|
+
MCP server for Dubai real estate data. Query 1.6M+ DLD sales transactions and 9.5M+ Ejari rental contracts.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uvx dld-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Claude Desktop Setup
|
|
33
|
+
|
|
34
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"dld": {
|
|
40
|
+
"command": "uvx",
|
|
41
|
+
"args": ["dld-mcp"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Tool: query_dld
|
|
48
|
+
|
|
49
|
+
One flexible tool to query all Dubai property data.
|
|
50
|
+
|
|
51
|
+
### Parameters
|
|
52
|
+
|
|
53
|
+
| Parameter | Values | Default |
|
|
54
|
+
|-----------|--------|---------|
|
|
55
|
+
| area | Area name or building (fuzzy search) | required |
|
|
56
|
+
| type | `sales`, `rentals` | sales |
|
|
57
|
+
| property_type | `all`, `apartment`, `villa`, `townhouse` | all |
|
|
58
|
+
| bedrooms | `all`, `studio`, `1`, `2`, `3`, `4`, `5+` | all |
|
|
59
|
+
| date_from | YYYY-MM-DD | 12 months ago |
|
|
60
|
+
| date_to | YYYY-MM-DD | today |
|
|
61
|
+
| metric | `stats`, `count`, `list` | stats |
|
|
62
|
+
| limit | 1-50 (for list mode) | 10 |
|
|
63
|
+
|
|
64
|
+
### Examples
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
"What's the median price in Marina?"
|
|
68
|
+
→ query_dld(area="Marina")
|
|
69
|
+
|
|
70
|
+
"How many villas sold in Palm Jumeirah in 2024?"
|
|
71
|
+
→ query_dld(area="Palm", property_type="villa", date_from="2024-01-01", metric="count")
|
|
72
|
+
|
|
73
|
+
"Average rent for 2BR in Downtown"
|
|
74
|
+
→ query_dld(area="Downtown", type="rentals", bedrooms="2")
|
|
75
|
+
|
|
76
|
+
"Show me recent sales in JBR"
|
|
77
|
+
→ query_dld(area="JBR", metric="list", limit=10)
|
|
78
|
+
|
|
79
|
+
"Compare Business Bay vs Marina apartment prices"
|
|
80
|
+
→ Two calls with different areas
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Supported Aliases
|
|
84
|
+
|
|
85
|
+
Marina, JBR, Downtown, Palm, JVC, JLT, Business Bay, Sports City, Motor City, Silicon Oasis, Arabian Ranches, Discovery Gardens, International City, Creek Harbour, City Walk, Town Square, DAMAC Hills
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git clone https://github.com/level09/dld-mcp
|
|
91
|
+
cd dld-mcp
|
|
92
|
+
uv sync
|
|
93
|
+
uv run dld-mcp
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT - [OfferBrief](https://offerbrief.com)
|
dld_mcp-0.2.0/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# DLD MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server for Dubai real estate data. Query 1.6M+ DLD sales transactions and 9.5M+ Ejari rental contracts.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uvx dld-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Claude Desktop Setup
|
|
12
|
+
|
|
13
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"dld": {
|
|
19
|
+
"command": "uvx",
|
|
20
|
+
"args": ["dld-mcp"]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Tool: query_dld
|
|
27
|
+
|
|
28
|
+
One flexible tool to query all Dubai property data.
|
|
29
|
+
|
|
30
|
+
### Parameters
|
|
31
|
+
|
|
32
|
+
| Parameter | Values | Default |
|
|
33
|
+
|-----------|--------|---------|
|
|
34
|
+
| area | Area name or building (fuzzy search) | required |
|
|
35
|
+
| type | `sales`, `rentals` | sales |
|
|
36
|
+
| property_type | `all`, `apartment`, `villa`, `townhouse` | all |
|
|
37
|
+
| bedrooms | `all`, `studio`, `1`, `2`, `3`, `4`, `5+` | all |
|
|
38
|
+
| date_from | YYYY-MM-DD | 12 months ago |
|
|
39
|
+
| date_to | YYYY-MM-DD | today |
|
|
40
|
+
| metric | `stats`, `count`, `list` | stats |
|
|
41
|
+
| limit | 1-50 (for list mode) | 10 |
|
|
42
|
+
|
|
43
|
+
### Examples
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
"What's the median price in Marina?"
|
|
47
|
+
→ query_dld(area="Marina")
|
|
48
|
+
|
|
49
|
+
"How many villas sold in Palm Jumeirah in 2024?"
|
|
50
|
+
→ query_dld(area="Palm", property_type="villa", date_from="2024-01-01", metric="count")
|
|
51
|
+
|
|
52
|
+
"Average rent for 2BR in Downtown"
|
|
53
|
+
→ query_dld(area="Downtown", type="rentals", bedrooms="2")
|
|
54
|
+
|
|
55
|
+
"Show me recent sales in JBR"
|
|
56
|
+
→ query_dld(area="JBR", metric="list", limit=10)
|
|
57
|
+
|
|
58
|
+
"Compare Business Bay vs Marina apartment prices"
|
|
59
|
+
→ Two calls with different areas
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Supported Aliases
|
|
63
|
+
|
|
64
|
+
Marina, JBR, Downtown, Palm, JVC, JLT, Business Bay, Sports City, Motor City, Silicon Oasis, Arabian Ranches, Discovery Gardens, International City, Creek Harbour, City Walk, Town Square, DAMAC Hills
|
|
65
|
+
|
|
66
|
+
## Development
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/level09/dld-mcp
|
|
70
|
+
cd dld-mcp
|
|
71
|
+
uv sync
|
|
72
|
+
uv run dld-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT - [OfferBrief](https://offerbrief.com)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dld-mcp"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "MCP server for Dubai real estate - DLD transactions and Ejari rentals"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.10"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "OfferBrief", email = "hello@offerbrief.com" }
|
|
10
|
+
]
|
|
11
|
+
keywords = ["mcp", "dubai", "real-estate", "dld", "property", "ejari", "rentals", "uae"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"mcp>=1.0.0",
|
|
22
|
+
"httpx>=0.27.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
dld-mcp = "dld_mcp:main"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://offerbrief.com"
|
|
30
|
+
Repository = "https://github.com/level09/dld-mcp"
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["hatchling"]
|
|
34
|
+
build-backend = "hatchling.build"
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["src/dld_mcp"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
line-length = 120
|
|
41
|
+
target-version = "py310"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""MCP server for Dubai Land Department property data."""
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
from mcp.server.fastmcp import FastMCP
|
|
5
|
+
|
|
6
|
+
API_BASE = "https://offerbrief.com/api"
|
|
7
|
+
|
|
8
|
+
mcp = FastMCP(
|
|
9
|
+
"Dubai Land Department",
|
|
10
|
+
instructions="""Query Dubai property data: 1.6M+ DLD sales transactions and 9.5M+ Ejari rental contracts.
|
|
11
|
+
Use query_dld with filters for area, property type, bedrooms, dates, etc.
|
|
12
|
+
Supports fuzzy search and aliases (Marina, JBR, Downtown, Palm, JVC, JLT).""",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@mcp.tool()
|
|
17
|
+
def query_dld(
|
|
18
|
+
area: str,
|
|
19
|
+
type: str = "sales",
|
|
20
|
+
property_type: str = "all",
|
|
21
|
+
bedrooms: str = "all",
|
|
22
|
+
date_from: str = "",
|
|
23
|
+
date_to: str = "",
|
|
24
|
+
metric: str = "stats",
|
|
25
|
+
limit: int = 10,
|
|
26
|
+
) -> dict:
|
|
27
|
+
"""Query Dubai property data - sales transactions or rental contracts.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
area: Location to search (e.g., "Marina", "JBR", "Downtown", "Palm Jumeirah", or building name)
|
|
31
|
+
type: "sales" for DLD transactions, "rentals" for Ejari contracts
|
|
32
|
+
property_type: "all", "apartment", "villa", or "townhouse" (sales only)
|
|
33
|
+
bedrooms: "all", "studio", "1", "2", "3", "4", "5+"
|
|
34
|
+
date_from: Start date YYYY-MM-DD (default: last 12 months for sales, 24 for rentals)
|
|
35
|
+
date_to: End date YYYY-MM-DD (default: today)
|
|
36
|
+
metric: "stats" (aggregated statistics), "count" (just count), "list" (individual records)
|
|
37
|
+
limit: Max records for list mode (1-50, default 10)
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
For stats: median/avg/min/max prices, transaction count, total volume
|
|
41
|
+
For count: just the count of matching records
|
|
42
|
+
For list: individual transaction/contract records
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
- "How many villas sold in Palm Jumeirah in 2024?"
|
|
46
|
+
query_dld(area="Palm", property_type="villa", date_from="2024-01-01", metric="count")
|
|
47
|
+
|
|
48
|
+
- "Average rent for 2BR in Marina"
|
|
49
|
+
query_dld(area="Marina", type="rentals", bedrooms="2")
|
|
50
|
+
|
|
51
|
+
- "Recent sales in Downtown"
|
|
52
|
+
query_dld(area="Downtown", metric="list", limit=10)
|
|
53
|
+
|
|
54
|
+
- "Compare JBR vs Marina prices"
|
|
55
|
+
Call twice with different areas
|
|
56
|
+
"""
|
|
57
|
+
if not area or len(area) < 2:
|
|
58
|
+
return {"error": "area must be at least 2 characters"}
|
|
59
|
+
|
|
60
|
+
params = {
|
|
61
|
+
"area": area,
|
|
62
|
+
"type": type,
|
|
63
|
+
"property_type": property_type,
|
|
64
|
+
"bedrooms": bedrooms,
|
|
65
|
+
"metric": metric,
|
|
66
|
+
"limit": min(max(1, limit), 50),
|
|
67
|
+
}
|
|
68
|
+
if date_from:
|
|
69
|
+
params["date_from"] = date_from
|
|
70
|
+
if date_to:
|
|
71
|
+
params["date_to"] = date_to
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
with httpx.Client(timeout=30) as client:
|
|
75
|
+
r = client.get(f"{API_BASE}/query", params=params)
|
|
76
|
+
r.raise_for_status()
|
|
77
|
+
return r.json()
|
|
78
|
+
except httpx.HTTPStatusError as e:
|
|
79
|
+
if e.response.status_code == 404:
|
|
80
|
+
return e.response.json()
|
|
81
|
+
return {"error": f"API error: {e.response.status_code}"}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def main():
|
|
85
|
+
mcp.run()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|