ClimaMX MCP
README.md
# ClimaMX MCP
An MCP (Model Context Protocol) server that lets AI assistants answer **Mexico weather questions** using official public data.
Ask something like *“What’s the weather today in Guadalajara, Jalisco?”* and the agent resolves the municipality, fetches the SMN forecast, and replies with real temperatures, sky conditions, and rain probability.


---
## Why this project
Most weather demos depend on commercial APIs. This one wires together **two Mexican government data sources** behind a clean MCP tool:
| Source | Role |
|--------|------|
| **INEGI** | Resolve municipality / state names → geo IDs |
| **CONAGUA / SMN** | Daily municipal forecast (compressed national dataset) |
The agent never handles gzip payloads or multi‑megabyte JSON. The server does the heavy work and returns a small, structured result.
---
## Features
- **One MCP tool:** `pronosticoCiudad(ciudad, estado?)`
- **Accent‑tolerant lookup** (e.g. `merida` + `Yucatan` → Mérida, Yucatán)
- **Ambiguity handling** — when several municipalities match, returns candidates so the agent can ask the user which state to use
- **Gzip decompression + filtering** of the national SMN feed
- **In‑memory cache** (15 minutes) to avoid re‑downloading ~5 MB on every request
- **No API keys** — public endpoints only
---
## Architecture
```
User → Agent → MCP tool (pronosticoCiudad)
│
├─► INEGI (name → ides / idmun)
└─► CONAGUA/SMN method=1 (gzip JSON → filter → today's forecast)
```
**Response statuses the agent understands:**
| Status | Meaning |
|--------|---------|
| `ok` | Forecast returned for that municipality |
| `ambiguo` | Several matches — ask the user for the state |
| `no_encontrado` | No municipality found |
| `error` | Network / unexpected failure |
---
## Project structure
```text
ClimaMX-MCP/
├── server.py # MCP server + tool registration
├── inegi.py # Municipality resolution (INEGI)
├── conagua.py # Forecast download, decompress, filter, cache
├── requirements.txt
└── README.md
```
---
## Requirements
- Python 3.10+
- [Cursor](https://cursor.com) (or any MCP‑compatible client)
---
## Setup
```bash
git clone https://github.com/danielvillasrc/ClimaMX-MCP.git
cd ClimaMX-MCP
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txt
```
---
## Configure in Cursor
Add the server to your MCP config (`~/.cursor/mcp.json` or project `.cursor/mcp.json`):
```json
{
"mcpServers": {
"clima-mx-server": {
"command": "C:\\path\\to\\ClimaMX-MCP\\.venv\\Scripts\\python.exe",
"args": [
"C:\\path\\to\\ClimaMX-MCP\\server.py"
]
}
}
}
```
On macOS / Linux, point `command` at `.venv/bin/python` instead.
Reload MCP (or restart Cursor). You should see the tool **`pronosticoCiudad`**.
---
## Usage examples
In Cursor chat:
- *What's the weather today in Guadalajara, Jalisco?*
- *Clima hoy en Mérida, Yucatán*
- *Weather in Zapopan, Jalisco*
Example successful payload (simplified):
```json
{
"status": "ok",
"ides": "14",
"idmun": "39",
"municipio": "Guadalajara",
"estado": "Jalisco",
"pronostico": [
{
"dia": "0",
"tmax": "30.5",
"tmin": "13.2",
"cielo": "Cielo nublado",
"prob_lluvia": "90",
"precipitacion_mm": "10.2"
}
]
}
```
---
## Manual smoke tests
With the virtualenv active:
```bash
python inegi.py
python conagua.py
```
These scripts exercise municipality lookup and forecast filtering without starting the MCP server.
---
## Design notes
- SMN `method=1` returns the **full national** daily forecast as gzip. The server decompresses, filters by `ides` / `idmun`, and keeps **today** (`ndia == "0"`).
- INEGI’s name search is accent‑sensitive. When a state is provided, a fallback lists that state’s municipalities and matches with accent‑stripped comparison.
- IDs are compared as **strings** to match SMN’s JSON shape (`"14"`, `"39"`).
---
## Data sources
- [SMN / CONAGUA Web Service](https://smn.conagua.gob.mx/es/web-service-api)
- [INEGI Geoestadística catalog API](https://www.inegi.org.mx/servicios/catalogounico.html)
---
## Limitations
- Forecast coverage is municipal (Mexico), not street‑level.
- First uncached CONAGUA call downloads a multi‑MB payload (then cached for 15 minutes).
- Municipality name ambiguity depends on what INEGI’s search returns for a given query.
---
## License
MIT — feel free to use and adapt.
---
## Author
Built as a portfolio project to practice **MCP servers**, **public API integration**, and **agent‑friendly tool design** with real Mexican open data.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues