ZIP-County Crosswalk MCP
ZIP-County Crosswalk MCP: consulta relaciones de código postal a condado utilizando los datos oficiales de HUD, incluido el filtrado por superposición de población para códigos postales que cruzan límites de condado.
Documentación
Servidor MCP de Crosswalk ZIP↔Condado
Un servidor de Protocolo de Contexto de Modelo (MCP) que permite a Claude consultar relaciones de ZIP a condado y de condado a ZIP, utilizando la API oficial de Crosswalk de Códigos ZIP del USPS de HUD — incluyendo filtrado por superposición de direcciones residenciales, ya que los códigos ZIP cruzan rutinariamente las líneas de los condados.
Arquitectura
flowchart LR
Claude -->|MCP tool call| Server[zip-county-mcp server]
Server -->|overlap ratios| HUD[HUD USPS Crosswalk API]
Server -->|county names| BQ[(BigQuery:\ngeo_us_boundaries)]
Por qué existe esto
Los códigos ZIP y los condados no coinciden de manera limpia — un solo ZIP puede extenderse a través de varios condados, cada uno con una proporción diferente de las direcciones residenciales de ese ZIP. La mayoría de las búsquedas simples de ZIP↔condado ignoran esto y solo devuelven una respuesta, que a menudo es incorrecta para el condado que contiene una pequeña porción del ZIP. Este servidor expone los datos reales de proporción de superposición de HUD para que un llamador pueda filtrar porciones insignificantes mediante un umbral de min_overlap_pct, y obtener nombres de condado precisos a través de un conjunto de datos público de BigQuery.
Ejemplo: el ZIP 77494 (Katy, TX) en realidad está dividido entre tres condados — Fort Bend (83.4%), Harris (16.5%) y Waller (0.17%). Un llamador que solo quiera condados que constituyan significativamente ese ZIP puede establecer min_overlap_pct=5 y obtener solo Fort Bend y Harris.
Cómo se mide realmente la superposición
El porcentaje de superposición proviene directamente del campo res_ratio de HUD, y vale la pena ser precisos sobre qué es ese campo (verificado contra la documentación de la API de HUD, no asumido):
- Es una proporción de direcciones residenciales, no de población/recuento de personas. Una dirección de una sola persona y una dirección de cinco personas cuentan ambas como "1" hacia la proporción — las direcciones son un proxy razonable para la población, pero no la misma medición.
- El denominador cambia con la dirección de la consulta. Para
zip_to_county(HUDtype=2),res_ratioes direcciones-en-este-condado ÷ direcciones-en-todo-el-ZIP. Parazips_in_county(HUDtype=7, la búsqueda inversa), es direcciones-en-este-ZIP ÷ direcciones-en-todo-el-condado. Mismo nombre de campo, diferente denominador — por eso un condado populoso como Harris muestra docenas de ZIPs a solo 1-3% cada uno, mientras que un solo ZIP puede mostrar un condado al 80%+: los dos porcentajes no se miden contra el mismo total.
Estado
Las tres herramientas están implementadas, probadas (7 pruebas que pasan, pytest) y verificadas de extremo a extremo contra datos en vivo de HUD + BigQuery y una conexión real de Claude Desktop.
Configuración
- Obtén una cuenta gratuita de API de HUD y un token Bearer en huduser.gov.
- Confirma que tienes acceso a BigQuery para
bigquery-public-data.geo_us_boundaries(por ejemplo, a través degcloud auth application-default login). - Copia
.env.examplea.envy completaHUD_API_TOKENy tu proyecto de Google Cloud. - Crea un virtualenv con Python 3.10+ (el paquete
mcplo requiere — en macOS elpython3del sistema a menudo es más antiguo, así que verificapython3 --versionprimero) e instala las dependencias:python3 -m venv .venv .venv/bin/pip install -r requirements.txt - Ejecútalo:
.venv/bin/python3 server.py
Conexión a Claude Desktop
Agrega una entrada a tu claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
"mcpServers": {
"zip-county-mcp": {
"command": "/absolute/path/to/zip-county-mcp/.venv/bin/python3",
"args": ["/absolute/path/to/zip-county-mcp/server.py"]
}
}
Cierra y vuelve a abrir completamente Claude Desktop (los servidores MCP solo se cargan al inicio), luego prueba una de las preguntas a continuación.
Ejemplo de uso
Una vez conectado, simplemente pregúntale a Claude en español sencillo — él elige la herramienta y los argumentos correctos por sí mismo. Algunos ejemplos reales (verificados contra datos en vivo):
Consulta un solo ZIP:
"¿En qué condado está el ZIP 77002?"
Claude llama a zip_to_county("77002") → el ZIP 77002 (Houston, TX) está completamente en el Condado de Harris, TX (FIPS 48201) — 100% de superposición.
Un ZIP que cruza líneas de condado:
"¿Con qué condados se superpone el ZIP 77494, y en qué medida?"
Claude llama a zip_to_county("77494") → tres condados: Fort Bend (83.4%), Harris (16.5%), Waller (0.17%). Haz una pregunta de seguimiento como "solo los que tengan al menos 5%" y volverá a llamar con min_overlap_pct=5, eliminando la porción insignificante de Waller.
Búsqueda inversa — ZIPs dentro de un condado:
"¿Qué códigos ZIP están en el Condado de Harris, Texas?" (o dale el código FIPS, 48201, directamente)
Claude llama a zips_in_county("48201") → una lista de cada ZIP que tiene una proporción significativa de las direcciones residenciales del Condado de Harris, ordenados por superposición.
Una lista de códigos ZIP a la vez:
"¿En qué condados están los códigos ZIP 77002, 77494 y 10001?"
Claude llama a batch_zip_to_county(["77002", "77494", "10001"]) → un resultado por ZIP en una sola respuesta, sin consultar BigQuery una vez por ZIP detrás de escena.
Herramientas (alcance v1)
zip_to_county(zip_code, min_overlap_pct=0)— condado(s) para un ZIP, con % de superposiciónzips_in_county(county_fips, min_overlap_pct=0)— códigos ZIP en un condado, con % de superposiciónbatch_zip_to_county(zip_codes, min_overlap_pct=0)— igual que el anterior, múltiples ZIPs a la vez
Fuera del alcance para v1: consultas a nivel de tracto censal, crosswalks de CBSA/distrito congresional, capa de caché, otros tipos de geografía.
Pruebas
.venv/bin/pip install -r requirements.txt
.venv/bin/python3 -m pytest tests/ -v
Las pruebas simulan las respuestas de la API de HUD (httpx.MockTransport) y la búsqueda de nombres de BigQuery, por lo que se ejecutan en aproximadamente un segundo sin necesidad de token en vivo ni acceso a BigQuery.