cdmx-mcp
The cdmx-mcp server gives AI models direct, code-free access to Mexico City's open data sources — crime, emergency calls, air quality, bike sharing, and business listings.
Generic Dataset Tools
list_datasets— Search and browse the full catalog ondatos.cdmx.gob.mxby free-text querydescribe_dataset— Get schema (columns, types, row count) and metadata for any dataset; supports shortcuts:fgj,911,ids,airequery_records— Run SQL-style queries (SELECT,WHERE,ORDER BY, pagination) against any CDMX dataset via CKAN's datastoreaggregate— Perform server-sideGROUP BYaggregations (e.g., count crimes per borough) on any dataset
Specialized Tools
crime_hotspots— Find top neighborhoods/boroughs by crime count from FGJ records, filterable by year, alcaldía, and crime categoryecobici_status— Get real-time ECOBICI bike-share station availability (bikes and docks) by station ID or proximity (lat/lng + radius)air_quality_now— Retrieve the latest SIMAT air quality index readings, optionally filtered by zone (e.g., NOROESTE, CENTRO)denue_near— Find businesses near a geographic point via INEGI's DENUE API (requires a free INEGI token), filterable by keyword and radius
Utility
cache_stats— View in-memory cache performance (TTL-based: 15s for real-time data, 10min for queries, 1h for catalog)
Designed to integrate with AI clients like Claude Code, Claude Desktop, and Cursor via the Model Context Protocol (MCP).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cdmx-mcp show me the top 5 crime types in Cuauhtémoc this year"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
cdmx-mcp
Model Context Protocol for Mexico City's open data. Give Claude direct access to crime, 911, air quality, ECOBICI, and DENUE — without writing a single line of ingestion code.
"¿Cuáles son las 10 colonias con más delitos en Cuauhtémoc en 2025?"
↓ Claude llama crime_hotspots(year=2025, alcaldia="CUAUHTEMOC", top_n=10)
↓ cdmx-mcp traduce a SQL contra CKAN
↓ Claude te contesta con la tabla + análisis, en segundos📋 Prerequisites
You need Python 3.10+ and uv (a modern Python package manager — replaces pip + venv + pyenv in a single binary).
Install uv
curl -LsSf https://astral.sh/uv/install.sh | shOr with Homebrew (macOS):
brew install uvIn PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Or with winget:
winget install --id=astral-sh.uv -eOr with Scoop:
scoop install uvVerify that it is installed:
uv --version # → uv 0.5.x o similarInstall Python (if you don't have it)
uv can download and install Python for you — you don't need to install it manually:
uv python install 3.12However, if you prefer to install it manually:
macOS:
brew install python@3.12or from https://www.python.org/downloads/Windows:
winget install Python.Python.3.12or from the Microsoft StoreLinux (Ubuntu/Debian):
sudo apt install python3.12 python3.12-venvLinux (Arch):
sudo pacman -S python
Verify:
python3 --version # → Python 3.10.x o superior💡 With
uvyou don't need to activate venvs or fight with versions —uv syncreadspyproject.toml+uv.lockand sets everything up on its own.
Related MCP server: MobusMCP
⚡ Quickstart — 30 seconds
git clone https://github.com/devcsar/cdmx-mcp.git
cd cdmx-mcp
uv sync # instala Python + dependencias
uv run python tests/smoke_test.py # verifica: debe decir "smoke: OK"It is already installed. Now connect it to your preferred client:
Claude Code
claude mcp add cdmx -- uv --directory "$(pwd)" run cdmx-mcp
claude # dentro de la sesión: /mcpOr simply open this directory with claude and it will automatically detect the .mcp.json.
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config) and paste:
{
"mcpServers": {
"cdmx": {
"command": "uv",
"args": ["--directory", "/ruta/absoluta/a/cdmx-mcp", "run", "cdmx-mcp"]
}
}
}Restart Claude Desktop. Full details by OS → QUICKSTART.md.
Cowork
Paste the same JSON into the Cowork MCP editor, or point to the .mcp.json in the repo.
🎯 First test prompt
Copy and paste into Claude:
List the 10 most frequent types of crime in the Cuauhtémoc borough during 2025. Then create a markdown table with bar emojis.
Claude automatically chooses crime_hotspots and answers with real data. More prompts in PROMPTS.md.
📊 What it covers
Source | Covered via | Freshness |
FGJ — Investigation files (crimes) |
| monthly |
911 / LOCATEL — emergency calls |
| monthly |
SIMAT — Air quality |
| hourly |
ECOBICI — bikes/docks in real time | GBFS (standard feed) | 🟢 live |
DENUE (INEGI) — economic units | INEGI public API | quarterly |
Post-migration note: in April 2026 the CDMX portal migrated from OpenDataSoft to CKAN 2.10. Queries now go through
/api/3/action/datastore_search_sql(real PostgreSQL). Dataset slugs were preserved.
🛠 Exposed Tools (9 total)
Generic — work with any dataset on the portal:
Tool | What it does |
| Search the full catalog |
| Real schema (columns, types, total rows) |
| SQL query via |
| GROUP BY server-side |
Recipes — shortcuts for the top 5:
Tool | What it does |
| Top neighborhoods/boroughs by crime |
| Real-time free bikes/docks |
| Most recent SIMAT index |
| Businesses near a point |
Plus cache_stats() and 2 resources (cdmx://guide/fgj, cdmx://guide/top5).
Shortcuts supported as dataset_id: fgj · 911 · ids · aire.
🧪 Verify it works
# Test offline (no golpea el portal)
uv run python tests/smoke_test.py
# → smoke: OK
# Test live (opcional — consulta real a datos.cdmx.gob.mx)
CDMX_MCP_LIVE=1 uv run python tests/live_test.py
# → live: OKThe CI runs the smoke test on Python 3.10, 3.11, and 3.12 on every push.
🔐 Optional token for DENUE
denue_near requires a free INEGI token:
Register at https://www.inegi.org.mx/servicios/api_denue.html (takes 2 min)
Export it before starting Claude Desktop/Code:
export INEGI_TOKEN=tu_tokenOr add it to the env of your JSON config — see config/claude_desktop_config.example.json.
🏗 Architecture
Claude (Desktop / Cowork / Code)
│ stdio · JSON-RPC
▼
cdmx_mcp.server (FastMCP)
│
┌──────┴──────┬───────────┬──────────┐
▼ ▼ ▼ ▼
ckan gbfs denue cache
(datos.cdmx) (ECOBICI) (INEGI) (TTL + LRU)CKAN covers 4 of the 5 sources (FGJ, 911, air, IDS) with the same API (
/api/3/action/*).describe_datasetusespackage_show+datastore_searchto expose the real schema.query_recordsandaggregatedelegate todatastore_search_sql(real PostgreSQL: identifiers with", literals with').ECOBICI is consumed via GBFS (standard feed; also overridable via
ECOBICI_GBFS_URL).Cache in memory with TTL per tool: 15 s for real-time, 10 min for queries, 1 h for catalog.
No tokens except DENUE (optional).
📚 Learn more
PROMPTS.md— library of ready-to-copy/paste prompts grouped by domain (crime, mobility, air, business, combos).QUICKSTART.md— step-by-step installation by operating system + troubleshooting.examples/— specific demos by channel:demo-cowork.md· prompts for Cowork (non-technical stakeholders).demo-claude-desktop.md· guided chat flow.demo-claude-code.md· advanced terminal exercises with pandas/matplotlib.
🤝 Contributing
The server is designed to be easily extended.
To add a new source:
Create
src/cdmx_mcp/adapters/<source>.pywith functions that return dicts in the form{"results": [...], "total_count": N}.Wrap them with
cache.cached(...)with an appropriate TTL.Expose them in
server.pywith@mcp.tool()and a clear docstring (Claude reads it).Add the name to the
expectedset intests/smoke_test.py.
Run local CI:
uv run python tests/smoke_test.py
CDMX_MCP_LIVE=1 uv run python tests/live_test.py # requiere internetIssues and PRs are welcome. The .github/workflows/ci.yml workflow validates that everything compiles in Python 3.10 / 3.11 / 3.12.
📄 License
MIT · built at Impact Lab CDMX 01 (April 2026) by rohan.mx · csar.dev.
Extend
To add a new source:
Create
src/cdmx_mcp/adapters/<source>.pywith functions that return dicts.Wrap with
cache.cached(...)for TTL.Expose in
server.pywith@mcp.tool().
License
MIT.
Available Tools
9 toolsaggregateA
Server-side aggregation (GROUP BY + metric) via CKAN datastore SQL.
Example: aggregate("fgj", group_by="alcaldia_hecho", metric='count(*) as delitos', where="anio_hecho=2025").
Inputs: dataset_id (required), group_by (required), metric, where, +1 more. Returns: result
air_quality_nowC
Most recent air-quality index rows from SIMAT (via datos.cdmx).
Args: zone: optional zone filter (e.g. "NOROESTE", "CENTRO", "SURESTE").
Inputs: zone, limit. Returns: result
cache_statsB
Return cdmx-mcp cache stats (for demos — shows how much we saved).
Inputs: no named parameters. Returns: result
crime_hotspotsB
Top colonies/alcaldías by crime count (FGJ carpetas).
Args: year: filter by anio_hecho (defaults to 2025). alcaldia: optional alcaldía filter (e.g. "CUAUHTEMOC"). UPPERCASE. category: optional crime category filter (e.g. "ROBO DE VEHICULO"). top_n: how many rows to return.
Inputs: year, alcaldia, category, top_n. Returns: result
denue_nearC
Economic units (businesses) near a point (INEGI DENUE).
Requires env INEGI_TOKEN. Free registration:
https://www.inegi.org.mx/servicios/api_denue.html
Inputs: lat (required), lng (required), radius_m, keyword, +1 more. Returns: result
describe_datasetA
Return schema and metadata for a dataset on datos.cdmx.gob.mx.
Use shortcut ids: "fgj", "911", "ids", "aire".
Inputs: dataset_id (required). Returns: result
ecobici_statusA
Live bike/dock availability from ECOBICI (GBFS).
Pass station_id for one station, or near_lat/near_lng + radius_m to
find the closest ones. Omit all to get the full snapshot (throttled).
Inputs: station_id, near_lat, near_lng, radius_m, +1 more. Returns: result
list_datasetsB
List datasets on datos.cdmx.gob.mx. Optional free-text search.
Args: search: free-text query (searches title and description). limit: max datasets to return (1-100).
Inputs: search, limit. Returns: result
query_recordsA
Query records from a CDMX dataset (CKAN datastore, PostgreSQL).
Args: dataset_id: id on datos.cdmx.gob.mx (or shortcut: fgj, 911, ids, aire). where: SQL-ish WHERE, e.g. anio_hecho=2025 AND alcaldia_hecho="BENITO JUAREZ". String literals can use single or double quotes; identifiers are quoted automatically. select: comma-separated columns (for fewer tokens). order_by: e.g. "fecha_hecho desc". limit: 1-100. Defaults to 50. offset: for pagination.
Inputs: dataset_id (required), where, select, order_by, +2 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Most tools have distinct purposes targeting different CDMX data domains (crime, air quality, business, bikes, datasets), but some overlap exists between 'aggregate' and 'query_records' as both query datasets with SQL-like capabilities. The descriptions help differentiate them, with 'aggregate' focused on server-side GROUP BY operations and 'query_records' on general record retrieval.
Naming conventions are mixed but generally readable. Most tools use snake_case (e.g., 'air_quality_now', 'crime_hotspots'), but there are deviations like 'denue_near' (abbreviation) and 'ecobici_status' (brand name). Verb styles vary from descriptive nouns ('cache_stats') to action-oriented phrases ('list_datasets'), lacking a uniform pattern.
With 9 tools, the count is well-scoped for a city data server covering multiple domains (crime, environment, transportation, business). Each tool serves a clear purpose, such as querying datasets, retrieving specific data types, or listing metadata, making the set comprehensive without being overwhelming.
The toolset provides strong coverage for accessing and querying CDMX open data, including listing, describing, and querying datasets, along with specialized tools for crime, air quality, bikes, and businesses. Minor gaps exist, such as no explicit update or delete operations (reasonable for read-only public data) and limited filtering options in some tools, but core workflows are well-supported.
Maintenance
Related MCP Connectors
Read-only Google Ads, GA4 and Search Console data for Claude, with no Google Cloud setup.
Connect your ads, shop, analytics, social, CRM and finance platforms once, then let Claude, ChatGPT, Cursor or any MCP client read, join and explain your numbers. Public statistics from the World Bank, IMF, Eurostat, OECD, WHO and SEC filings come as context, searchable and chartable from the same tools. Read-only by design, every number carries its source.
INEGI DENUE MCP — Mexico's directory of economic units (~6M businesses).
Public records for every city: permits, alerts, wildfires, laws and funding, linked to the source.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to connect to and interact with SQLite, SQL Server, PostgreSQL, and MySQL databases through natural language. Supports executing queries, managing tables, exporting data, and storing business insights with authentication options including AWS IAM.782 npmMIT
- AlicenseNot gradedqualityCmaintenanceSearch, preview, and analyze datasets from 20+ platforms and millions of datasets via a single MCP connector. Works with Claude instantly7 npm29MIT

city-data-mcpofficial
AlicenseAqualityDmaintenanceAn MCP server that gives Claude deep access to US public data -- demographics, economics, crime, employment, weather, housing, transit, schools, budgets, and more across 30+ cities for government intelligence workflows.28MIT- AlicenseAqualityDmaintenanceProvides Claude with access to NYC public property data including property details, sales history, comparable sales, tax benefits, and rent stabilization analysis using natural language.7MIT