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-mcpshow 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").
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | ||
| group_by | Yes | ||
| metric | No | count(*) as total | |
| where | No | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden for behavioral disclosure. It mentions 'Server-side aggregation' which implies read-only behavior, but doesn't disclose important details like rate limits, authentication requirements, error conditions, or what happens with large datasets. The example helps but doesn't constitute comprehensive behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise and well-structured - one sentence explaining the purpose, followed by a comprehensive example that demonstrates usage. Every element earns its place, with the example serving dual purpose of showing syntax and parameter semantics. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema (which handles return values) and the description provides excellent parameter semantics via example, the description is reasonably complete for a read-only aggregation tool. However, with no annotations and complex aggregation behavior, it could benefit from more behavioral context about limitations, performance, or error handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must compensate, and it does so effectively through the concrete example that demonstrates how all 5 parameters work together. The example shows dataset_id='fgj', group_by='alcaldia_hecho', metric='count(*) as delitos', where='anio_hecho=2025', and implies limit uses default. This provides excellent semantic understanding beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs 'Server-side aggregation (GROUP BY + metric) via CKAN datastore SQL' - a specific verb (aggregation) with resource (CKAN datastore) and method (SQL). It distinguishes from siblings like 'query_records' by focusing specifically on aggregation operations rather than general queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. While it mentions CKAN datastore SQL, it doesn't explain when aggregation is appropriate versus using 'query_records' or other sibling tools, nor does it mention any prerequisites or exclusions for usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_quality_nowC
Most recent air-quality index rows from SIMAT (via datos.cdmx).
Args: zone: optional zone filter (e.g. "NOROESTE", "CENTRO", "SURESTE").
| Name | Required | Description | Default |
|---|---|---|---|
| zone | No | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It mentions retrieving 'most recent' rows, implying a time-based query, but doesn't disclose behavioral traits like rate limits, data freshness, authentication needs, or error handling. For a data retrieval tool with zero annotation coverage, this is a significant gap in transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded, with the main purpose stated first followed by parameter details. The two sentences earn their place by defining the tool and clarifying the zone parameter. It could be slightly more structured but avoids unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema (which handles return values), no annotations, and low schema coverage, the description is moderately complete. It covers the purpose and one parameter but misses details on the 'limit' parameter and behavioral aspects. For a simple data query tool, this is adequate but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the 'zone' parameter with examples ('NOROESTE', 'CENTRO', 'SURESTE') and notes it's optional, adding meaning beyond the schema. However, it doesn't mention the 'limit' parameter at all, leaving it undocumented. With 2 parameters and partial coverage, this meets the baseline for moderate value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves 'most recent air-quality index rows from SIMAT (via datos.cdmx)', which specifies the verb (retrieve), resource (air-quality index rows), and data source. However, it doesn't explicitly differentiate from sibling tools like 'describe_dataset' or 'query_records' that might also access air quality data, though the 'most recent' aspect provides some distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description mentions a zone filter but doesn't explain when to apply it or compare to other tools like 'aggregate' or 'query_records' that might handle similar data. Usage context is implied but not explicitly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cache_statsB
Return cdmx-mcp cache stats (for demos — shows how much we saved).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool returns cache stats and is for demos, but doesn't disclose key behavioral traits such as whether it's read-only, its performance characteristics (e.g., latency), authentication needs, rate limits, or what specific stats are included (e.g., hit rates, size). The mention of 'shows how much we saved' adds some context about purpose, but lacks operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise with a single sentence that efficiently conveys the purpose and context: 'Return cdmx-mcp cache stats (for demos — shows how much we saved).' It's front-loaded with the core action and includes a brief parenthetical for additional context, with zero wasted words. Every part of the sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 0 parameters, 100% schema coverage, and an output schema exists (so return values are documented elsewhere), the description is minimally complete. However, as a tool with no annotations, it lacks behavioral context (e.g., safety, performance) that would be helpful for an agent. The description covers purpose and implied usage but doesn't fully address operational aspects, making it adequate but with gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description doesn't add parameter information beyond the schema, but since there are no parameters, this is acceptable. Baseline is 4 for 0 parameters, as the description doesn't need to compensate for any gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Return cdmx-mcp cache stats' with the specific verb 'return' and resource 'cache stats'. It distinguishes from siblings by mentioning 'for demos — shows how much we saved', which hints at a monitoring/evaluation function rather than data retrieval or analysis like other tools. However, it doesn't explicitly differentiate from all siblings (e.g., 'describe_dataset' might also provide metadata).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context with 'for demos — shows how much we saved', suggesting this tool is for demonstration or evaluation purposes rather than operational use. However, it doesn't provide explicit guidance on when to use this tool versus alternatives (e.g., vs. 'describe_dataset' for general metadata or 'list_datasets' for inventory), nor does it specify exclusions or prerequisites. The guidance is implied but not comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | ||
| alcaldia | No | ||
| category | No | ||
| top_n | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the tool returns 'Top colonies/alcaldías by crime count' and lists parameters, but lacks details on permissions, rate limits, data freshness, error handling, or output format. For a data query tool with zero annotation coverage, this leaves significant gaps in understanding its operational behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the purpose, followed by a concise 'Args:' section detailing each parameter. Every sentence earns its place by providing essential information without redundancy. The formatting with bullet-like parameter explanations enhances readability while maintaining brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (4 parameters, no annotations, but has an output schema), the description is reasonably complete. It covers the purpose and all parameters semantically. With an output schema present, it doesn't need to explain return values. However, it could improve by adding more behavioral context or usage guidelines to fully compensate for the lack of annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It effectively adds meaning for all four parameters: 'year' specifies filtering by 'anio_hecho' with a default; 'alcaldia' notes it's optional and requires UPPERCASE; 'category' gives an example; and 'top_n' explains it controls row count. This provides clear semantic context beyond the bare schema, though it could include more on valid values or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Top colonies/alcaldías by crime count (FGJ carpetas).' This specifies the verb ('Top'), resource ('colonies/alcaldías'), and data source ('FGJ carpetas'), making it distinct from siblings like 'aggregate' or 'query_records'. However, it doesn't explicitly differentiate from potential similar tools beyond the server's current list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention any prerequisites, compare it to siblings like 'aggregate' or 'query_records', or specify scenarios where it's preferred. The usage context is implied through parameter descriptions but not explicitly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lng | Yes | ||
| radius_m | No | ||
| keyword | No | todos | |
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the need for an INEGI_TOKEN environment variable and a free registration link, which is useful for authentication. However, it doesn't describe behavioral traits like rate limits, response format, error handling, or whether this is a read-only operation. The mention of 'near a point' implies a query, but more details are needed for a mutation-aware agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded, with the core purpose stated first. The two sentences are efficient: one defines the tool, and the other covers authentication. There's no wasted text, making it easy to scan, though it could be slightly more structured (e.g., bullet points for parameters).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (5 parameters, no annotations, but an output schema exists), the description is incomplete. It covers authentication and the high-level purpose but misses parameter semantics and behavioral context. The output schema may handle return values, but without annotations, the description should do more to explain usage, constraints, and how results are structured. It's minimally viable but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It doesn't explain any of the 5 parameters (lat, lng, radius_m, keyword, limit). While it implies location-based searching, it provides no details on parameter meanings, units (e.g., meters for radius), default behaviors, or the 'keyword' parameter's purpose. This leaves significant gaps in understanding how to use the tool effectively.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Economic units (businesses) near a point (INEGI DENUE).' It specifies the verb ('near' implying search/locate) and resource ('economic units/businesses'), and identifies the data source (INEGI DENUE). However, it doesn't differentiate from sibling tools, which include unrelated functions like air quality or crime data, so it doesn't fully distinguish itself in context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It mentions the INEGI DENUE data source but doesn't explain if this is for specific types of businesses, geographic regions, or other contextual factors. No exclusions, prerequisites beyond the token, or comparisons to sibling tools are included.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_datasetA
Return schema and metadata for a dataset on datos.cdmx.gob.mx.
Use shortcut ids: "fgj", "911", "ids", "aire".
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool returns schema and metadata, which implies a read-only operation, but doesn't clarify aspects like whether it requires authentication, rate limits, error handling, or what the output format looks like (though an output schema exists). The mention of shortcut ids adds some context, but overall, the description lacks sufficient behavioral details for a mutation-free tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise and front-loaded: the first sentence clearly states the purpose, and the second sentence provides essential usage guidance with shortcut examples. There's no wasted text, and every sentence earns its place by adding specific value, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (1 parameter, no nested objects) and the presence of an output schema (which handles return values), the description is reasonably complete. It covers the purpose, provides key parameter semantics with shortcut ids, and offers basic usage hints. However, it lacks behavioral details like authentication or error handling, which are somewhat important even for a read-only tool with no annotations, keeping it from a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 1 parameter with 0% description coverage, so the description must compensate. It adds meaning by specifying that 'dataset_id' should use 'shortcut ids' like "fgj", "911", "ids", "aire", which clarifies the expected format and valid values beyond the schema's generic string type. This is valuable semantic information, though it doesn't cover all potential dataset IDs or explain the parameter's role in detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Return schema and metadata for a dataset on datos.cdmx.gob.mx.' This specifies the verb ('Return'), resource ('schema and metadata'), and target ('dataset on datos.cdmx.gob.mx'). However, it doesn't explicitly differentiate from siblings like 'list_datasets' (which likely lists available datasets) or 'query_records' (which queries data), though the distinction is somewhat implied by the focus on schema/metadata versus data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides some usage context by mentioning 'Use shortcut ids: "fgj", "911", "ids", "aire".' This implies when to use the tool (for these specific datasets) but doesn't explicitly state when to use it versus alternatives like 'list_datasets' or 'query_records'. There's no guidance on prerequisites, exclusions, or detailed comparisons, leaving the agent to infer usage from the purpose alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| station_id | No | ||
| near_lat | No | ||
| near_lng | No | ||
| radius_m | No | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively communicates that the data is 'live' (real-time), mentions the throttling constraint for the full snapshot option, and implies read-only behavior through data retrieval context. However, it doesn't specify rate limits beyond throttling, authentication requirements, or error handling for invalid parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is perfectly sized at three sentences with zero wasted words. It's front-loaded with the core purpose, followed by specific usage patterns, and ends with an important behavioral note about throttling. Every sentence earns its place by providing essential information for tool selection and invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (5 parameters with interaction patterns), no annotations, and the presence of an output schema (which handles return values), the description is complete enough. It covers purpose, all parameter semantics, usage guidelines, and key behavioral constraints. The output schema will document the response structure, so the description appropriately focuses on selection and invocation guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage (titles only provide basic labels), the description adds substantial value by explaining the semantic purpose of all parameters. It clarifies that station_id retrieves data for one station, near_lat/near_lng + radius_m finds closest stations, and omitting all gets a full snapshot. This goes well beyond what the schema provides, compensating fully for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: retrieving live bike/dock availability from ECOBICI using GBFS. It specifies the exact resource (ECOBICI bike/dock availability) and the data source (GBFS), distinguishing it from unrelated sibling tools like air_quality_now or crime_hotspots. The verb 'retrieve' is implied through the context of availability data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use different parameter combinations: use station_id for a single station, use near_lat/near_lng + radius_m for closest stations, or omit all for a full snapshot (with a throttling warning). It clearly distinguishes between these three usage scenarios, helping the agent select the appropriate approach based on the user's needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden for behavioral disclosure. It mentions the search capability and parameter defaults, but doesn't describe important behaviors like pagination, rate limits, authentication requirements, error conditions, or what the output looks like. For a list operation with zero annotation coverage, this leaves significant gaps in understanding how the tool behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely efficient - a single sentence states the core purpose with optional feature, followed by clear parameter explanations. Every element earns its place with no redundant information. The structure separates the high-level description from parameter details, making it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (list operation with search), no annotations, but with an output schema present, the description is minimally adequate. The output schema will handle return value documentation, so the description doesn't need to explain outputs. However, for a tool with no annotations, it should provide more behavioral context about how the listing works, what authentication is needed, or any limitations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates well by explaining both parameters: 'search' is described as a 'free-text query (searches title and description)' and 'limit' as 'max datasets to return (1-100)'. This adds meaningful context beyond the bare schema, though it doesn't cover all possible semantic nuances like search algorithm details or limit enforcement behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List datasets') and target resource ('on datos.cdmx.gob.mx'), making the purpose immediately understandable. It doesn't explicitly differentiate from sibling tools like 'describe_dataset' or 'query_records', but the core functionality is well-defined. The description avoids tautology by specifying the domain and search capability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'describe_dataset' or 'query_records'. It mentions an optional free-text search feature but doesn't explain when searching is appropriate versus other filtering methods. There are no usage prerequisites, exclusions, or comparisons to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | ||
| where | No | ||
| select | No | ||
| order_by | No | ||
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses some behavioral traits: it queries from a specific data source (CDMX dataset, CKAN datastore, PostgreSQL), mentions SQL-ish syntax for filtering, and notes defaults (limit defaults to 50). However, it lacks details on permissions, rate limits, error handling, or what the output looks like, leaving gaps for a query tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded: the first sentence states the purpose, followed by a structured 'Args:' section with bullet-like explanations for each parameter. Every sentence adds value, with no wasted words, making it efficient and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, query functionality) and no annotations, the description is largely complete: it covers purpose, parameter semantics, and basic behavior. However, it lacks details on authentication, error cases, or output format, though the presence of an output schema mitigates the need to explain return values. Slight gaps remain in behavioral context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds significant meaning beyond the schema: explains dataset_id shortcuts (fgj, 911, ids, aire), provides syntax examples for where, select, and order_by, clarifies string literal quoting, and states limit range (1-100) and defaults. This fully documents all 6 parameters with practical guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Query records from a CDMX dataset (CKAN datastore, PostgreSQL).' It specifies the verb ('query'), resource ('records'), and context ('CDMX dataset'), distinguishing it from siblings like 'aggregate' or 'list_datasets' which serve different functions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for usage by mentioning the CDMX dataset and CKAN datastore, but does not explicitly state when to use this tool versus alternatives like 'describe_dataset' or 'aggregate'. It implies usage for querying records but lacks explicit exclusions or comparisons to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
aggregate - First observed
air_quality_now - First observed
cache_stats - First observed
crime_hotspots - First observed
denue_near - First observed
describe_dataset - First observed
ecobici_status - First observed
list_datasets - First observed
query_records
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
INEGI DENUE MCP — Mexico's directory of economic units (~6M businesses).
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Normalized official data with provenance, aggregations, insights, free samples and agent access.
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.676 npmMIT
- AlicenseNot gradedqualityBmaintenanceSearch, preview, and analyze datasets from 20+ platforms and millions of datasets via a single MCP connector. Works with Claude instantly2 npm28MIT

city-data-mcpofficial
FlicenseAqualityDmaintenanceAn 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.28-- FlicenseAqualityDmaintenanceProvides Claude with access to NYC public property data including property details, sales history, comparable sales, tax benefits, and rent stabilization analysis using natural language.7-