Skip to main content
Glama
aviveldan

Datagov Israel MCP

by aviveldan
README.md
# DataGov Israel MCP Server

An MCP server for exploring Israeli government open data ([data.gov.il](https://data.gov.il)) β€” with built-in interactive visualizations powered by [MCP Apps](https://gofastmcp.com).

Search thousands of public datasets, profile their structure, generate charts, and plot geographic data on maps β€” all from your AI assistant.

[![Tests](https://github.com/aviveldan/datagov-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/aviveldan/datagov-mcp/actions/workflows/test.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

---

## What Can You Do With This?

### 🏠 Explore the Housing Market

Profile public housing datasets to understand unit sizes, locations, and availability:

![Dataset Profile β€” Public Housing](screenshots/demo-profile.png)

See which cities have the most demand in government housing lotteries:

![Housing Lottery Subscribers by City](screenshots/demo-bar-chart.png)

Understand the distribution of apartment sizes across the country:

![Distribution of Public Housing Unit Sizes](screenshots/demo-histogram.png)

Track housing unit availability over time:

![Housing Units Available per Lottery](screenshots/demo-line-chart.png)

### πŸ—ΊοΈ Map Public Infrastructure

Visualize education institutions across Israel:

![Education Institutions Map](screenshots/demo-edu-map.png)

Plot public transport stations:

![Public Transport Stations](screenshots/demo-map.png)

---

## Quick Start

### Installation

```bash
git clone https://github.com/aviveldan/datagov-mcp.git
cd datagov-mcp

# Create virtual environment and install (requires uv)
uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uv pip install -e ".[dev]"
```

### Using with Claude Desktop

```bash
fastmcp install claude-desktop server.py
```

Restart Claude Desktop β€” you'll see the DataGovIL tools available immediately.

### Try It with the MCP Inspector

```bash
fastmcp dev inspector server.py
```

This opens a web UI where you can browse tools, test them interactively, and preview MCP App visualizations in the **Apps** tab.

### Using with `fastmcp dev apps`

Preview the interactive visualization apps locally:

```bash
fastmcp dev apps server.py
```

---

## Example: Finding Real Estate Opportunities

Here's a real workflow for someone exploring the Israeli housing market:

```
You: "Search for discounted housing lottery datasets"

β†’ package_search(q="Χ“Χ™Χ¨Χ” Χ‘Χ”Χ Χ—Χ”")
  Found: "Χ Χͺונים ΧͺΧ§Χ•Χ€Χͺיים - ΧͺΧ›Χ Χ™Χͺ Χ“Χ™Χ¨Χ” Χ‘Χ”Χ Χ—Χ”" (Discounted Housing Program)
  Resource ID: 7c8255d0-49ef-49db-8904-4cf917586031

You: "Profile this dataset so I can understand what fields are available"

β†’ dataset_profile(resource_id="7c8255d0-49ef-49db-8904-4cf917586031")
  Shows: LamasName (city), Subscribers, Winners, PriceForMeter,
         LotteryHousingUnits, ProjectName, Neighborhood...

You: "Show me which cities have the most subscribers competing for units"

β†’ chart_generator(
    resource_id="7c8255d0-49ef-49db-8904-4cf917586031",
    chart_type="bar",
    x_field="LamasName",
    y_field="Subscribers",
    title="Housing Lottery Subscribers by City"
  )
  β†’ Interactive bar chart rendered in MCP Apps UI

You: "Now show the public housing units β€” map them and show me sizes"

β†’ dataset_profile(resource_id="c3a68837-9b7a-4ee7-bd92-130678dc8ae3")
  Shows: CityLmsName, NumOfRooms (avg 2.4), Floor, TotalArea (21-110 mΒ²)...

β†’ chart_generator(
    resource_id="c3a68837-9b7a-4ee7-bd92-130678dc8ae3",
    chart_type="histogram",
    x_field="TotalArea",
    title="Distribution of Housing Unit Sizes (mΒ²)"
  )
  β†’ Most units are 48-57 mΒ², with a long tail up to 110 mΒ²
```

**Insight:** Cities like Ashkelon and Sderot show 25,000-35,000 subscribers per lottery β€” that's intense competition. Smaller cities in the periphery (Umm al-Fahm, Nazareth) have far fewer. If you're flexible on location, your odds improve dramatically.

---

## Available Tools

### Core Data Tools

| Tool | Description |
|------|-------------|
| `status_show` | Get CKAN version and site info |
| `license_list` | List available dataset licenses |
| `package_list` | Get all dataset IDs |
| `package_search` | Search datasets with filters and sorting |
| `package_show` | Get detailed metadata for a specific dataset |
| `organization_list` | List all organizations |
| `organization_show` | Get details of a specific organization |
| `resource_search` | Search for resources within datasets |
| `datastore_search` | Query data within a specific resource |
| `fetch_data` | Convenience tool β€” find dataset by name and fetch its data |

### Visualization Tools (MCP Apps) πŸ“Š

These tools render interactive UI directly in MCP-compatible clients.

#### `dataset_profile`

Profile a dataset to understand its structure and quality.

- **Fields detected**: integer, number, string, coordinate
- **Statistics**: min, max, mean, null count, unique values
- **Output**: Interactive DataTable with search/filter

```
dataset_profile(resource_id="c3a68837-9b7a-4ee7-bd92-130678dc8ae3", sample_size=200)
```

#### `chart_generator`

Generate interactive charts from any dataset.

| Chart Type | Use Case |
|------------|----------|
| `histogram` | Distribution of numeric values (e.g., apartment sizes) |
| `bar` | Compare categories (e.g., subscribers per city) |
| `line` | Trends over time (e.g., housing units per lottery) |
| `scatter` | Correlations between two numeric fields |

```
chart_generator(
  resource_id="7c8255d0-49ef-49db-8904-4cf917586031",
  chart_type="bar",
  x_field="LamasName",
  y_field="Subscribers",
  title="Housing Lottery Subscribers by City",
  limit=50
)
```

#### `map_generator`

Plot geographic data on interactive Leaflet maps.

```
map_generator(
  resource_id="e873e6a2-66c1-494f-a677-f5e77348edb0",
  lat_field="Lat",
  lon_field="Long",
  limit=500
)
```

---

## Useful Resource IDs

Here are some interesting datasets to get started with:

| Dataset | Resource ID | Good For |
|---------|-------------|----------|
| ✈️ Flights (Χ˜Χ™Χ‘Χ•Χͺ) | `e83f763b-b7d7-479e-b172-ae981ddc6de5` | Bar charts by airline |
| 🏠 Public Housing (Χ“Χ™Χ•Χ¨ Χ¦Χ™Χ‘Χ•Χ¨Χ™) | `c3a68837-9b7a-4ee7-bd92-130678dc8ae3` | Histograms, profiling |
| 🎰 Housing Lotteries (Χ“Χ™Χ¨Χ” Χ‘Χ”Χ Χ—Χ”) | `7c8255d0-49ef-49db-8904-4cf917586031` | Bar/line charts |
| 🚌 Transport Stations (ΧͺΧ—Χ Χ•Χͺ) | `e873e6a2-66c1-494f-a677-f5e77348edb0` | Maps (has Lat/Long) |
| 🏫 Schools (ΧžΧ•Χ‘Χ“Χ•Χͺ Χ—Χ™Χ Χ•Χš) | `5c5d6bb0-755d-470d-84b6-d7dd3135ba9c` | Maps (UTM_X/UTM_Y) |

---

## Architecture

### MCP Apps

Visualization tools use [FastMCPApp](https://gofastmcp.com) providers with [prefab-ui](https://github.com/PrefectHQ/prefab-ui) components:

- **`DataProfile` app** β†’ `DataTable`, `Metric` components
- **`Charts` app** β†’ `BarChart`, `LineChart`, `ScatterChart`, `Histogram`
- **`Maps` app** β†’ `Embed` with Leaflet HTML

Tools registered via `@app.ui()` automatically get proper MCP Apps metadata and render in compatible clients.

### Async HTTP Layer

All API calls use `httpx.AsyncClient` with:
- 30-second timeout
- Automatic retries for 5xx errors
- Connection pooling

### Data Safety

- Numeric values from CKAN are coerced (handles `"25"` β†’ `25.0`)
- Map popup content is HTML-escaped to prevent XSS
- Line charts are sorted by x-axis for correct rendering

---

## Development

### Running Tests

```bash
pytest tests/ -v          # 39 tests
pytest tests/ --cov=datagov_mcp  # With coverage
```

### Code Style

```bash
ruff check .   # Lint
ruff format .  # Format
```

### Project Structure

```
datagov-mcp/
β”œβ”€β”€ datagov_mcp/
β”‚   β”œβ”€β”€ server.py          # Core CKAN tools + provider registration
β”‚   β”œβ”€β”€ apps.py            # FastMCPApp definitions (DataProfile, Charts, Maps)
β”‚   β”œβ”€β”€ visualization.py   # Visualization tools (@app.ui entry points)
β”‚   β”œβ”€β”€ api.py             # CKAN API helper
β”‚   └── client.py          # HTTP client
β”œβ”€β”€ tests/                 # 39 tests with HTTP mocking
β”‚   β”œβ”€β”€ test_api.py
β”‚   β”œβ”€β”€ test_contracts.py
β”‚   β”œβ”€β”€ test_tools.py
β”‚   └── test_visualization.py
β”œβ”€β”€ screenshots/           # Auto-generated demo screenshots
β”œβ”€β”€ server.py              # Entrypoint
└── pyproject.toml
```

---

## Contributing

We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

1. Fork the repository
2. Create a feature branch
3. Make changes with tests
4. Submit a pull request

---

## Troubleshooting

### Port Conflicts with MCP Inspector

```bash
pip install nano-dev-utils
python -c "from nano_dev_utils import release_ports; release_ports.PortsRelease().release_all()"
```

### Windows + OneDrive

Avoid running installation in OneDrive-synced folders. See [uv#7906](https://github.com/astral-sh/uv/issues/7906).

### Import Errors

```bash
uv pip install -e ".[dev]"
```

---

## License

MIT β€” see [LICENSE](./LICENSE).

## Acknowledgments

- Built with [FastMCP](https://gofastmcp.com) and [prefab-ui](https://github.com/PrefectHQ/prefab-ui)
- Data from [Israel Open Data Portal](https://data.gov.il)
- Maps powered by [Leaflet](https://leafletjs.com/) + [CARTO](https://carto.com/)
- Charts powered by [Recharts](https://recharts.org/) (via prefab-ui)

TDQS

B3/5.0

Scored across 10 tools

Disambiguation4/5

Most tools have distinct purposes, such as searching datastores vs. fetching data from APIs, but 'datastore_search' and 'resource_search' could be confused as both involve searching within datasets. The descriptions help clarify, but some overlap exists.

Naming Consistency4/5

Tools follow a consistent snake_case pattern with clear verb_noun structures like 'package_search' and 'organization_show', but 'fetch_data' deviates slightly with a less specific verb. Overall, the naming is predictable and readable.

Tool Count5/5

With 10 tools, the server is well-scoped for interacting with a data catalog, covering operations like listing, searching, and showing details for datasets, organizations, and resources. Each tool earns its place without being overwhelming.

Completeness4/5

The toolset provides good coverage for browsing and querying a CKAN-based data catalog, including CRUD-like operations for packages and organizations. Minor gaps exist, such as no tools for creating or updating datasets, but agents can work around this for read-only access.

Maintenance

ActivityInactive
ResponsivenessNo issues