ntc-cdmx-mcp
MCP server for querying Mexico City building regulations (NTC CDMX 2004/2017/2023) with RAG-powered answers, hybrid search, and precise section retrieval, including citations and validated calculations.
README
RAG · Chatbot experto en NTC CDMX (2004 / 2017 / 2023)
Sistema de Retrieval-Augmented Generation sobre las Normas Técnicas Complementarias del Reglamento de Construcciones de la Ciudad de México, con búsqueda híbrida (BM25 + embeddings multilingües + RRF) y citas por edición y numeral.
Estructura
RAG/
├── src/
│ ├── config.py # rutas y mapeo PDF → (edición, norma)
│ ├── extract.py # PDF → páginas de texto por norma (temp/extracted_text/)
│ ├── structure.py # páginas → secciones X.Y.Z (data/corpus/*.json)
│ ├── index_build.py # secciones → catálogo + BM25 + embeddings (data/index/)
│ ├── retrieve.py # retriever híbrido (BM25 + embeddings + RRF + numeral)
│ ├── answer.py # generador de respuestas con LLM (DeepSeek V4 Flash)
│ ├── calc.py # cálculos validados (viento, sismo, combinaciones)
│ ├── evaluate.py # evaluación recall@k con el dataset de 21k Q&A
│ └── finetune_gen.py # genera dataset RAG-formateado para fine-tune del generador
├── app/app.py # interfaz web (Streamlit)
└── scripts/run_all.py # orquesta el pipeline completo
Servidor MCP (para opencode, codex, Claude Desktop, etc.)
El proyecto se expone como un servidor MCP con tres tools:
| Tool | Qué hace |
|---|---|
answer_ntc(query) |
Responde con RAG + LLM (DeepSeek V4 Flash) citando edición, norma y numeral; también resuelve cálculos validados |
search_ntc(query, edition, norm, top_k) |
Devuelve las secciones relevantes en bruto |
get_section(edition, norm, numeral) |
Devuelve el texto completo de un numeral concreto |
Instalación automática (registra el servidor en opencode y/o codex):
.venv\Scripts\python.exe scripts\install_mcp.py # opencode + codex
.venv\Scripts\python.exe scripts\install_mcp.py --opencode # solo opencode
.venv\Scripts\python.exe scripts\install_mcp.py --codex # solo codex
Reinicia opencode/codex y el RAG estará disponible como tools (answer_ntc, etc.).
El servidor lee la API key del proveedor de RAG/.env, la variable de entorno
correspondiente o ~/.config/ntc-cdmx/.env.
Instalación con un solo comando (GitHub + uv)
uvx --from git+https://github.com/Sobrio25/ntc-cdmx-mcp ntc-cdmx-install
Ese comando instala y registra el MCP en opencode, Codex, Command Code y Kilo Code. Reinicia los
clientes y
answer_ntc, search_ntc y get_section estarán disponibles. El índice (BM25 +
embeddings) viaja dentro del paquete; la API key del proveedor se configura en
~/.config/ntc-cdmx/.env.
Para instalar solamente el ejecutable:
uv tool install git+https://github.com/Sobrio25/ntc-cdmx-mcp
Rendimiento al arrancar (evita timeouts del cliente)
El servidor MCP responde el handshake y las tools al instante (~1 s). El índice
y el modelo de embeddings (intfloat/multilingual-e5-small, ~130 MB) se cargan en
segundo plano; la primera llamada responde rápido usando solo BM25 y pasa a la
búsqueda híbrida completa en cuanto el modelo está listo. No se bloquea la
conexión del cliente, así que opencode/codex no marcan el servidor como timeout.
Solo la primera vez en una máquina nueva hay una espera adicional inevitable:
uvx --from git+... construye el paquete (~15 s) y descarga el modelo (~130 MB).
Instalar una sola vez con uv tool install evita la reconstrucción en cada arranque.
Probar el servidor manualmente:
ntc-cdmx # stdio (modo instalado)
.venv\Scripts\python.exe src\mcp_server.py # stdio (modo desarrollo)
Pipeline
# 1) Extraer y estructurar e indexar
.venv/Scripts/python.exe scripts/run_all.py --steps extract structure index
# 2) Evaluar recall del retriever (muestra 400 preguntas del dataset de 21k)
.venv/Scripts/python.exe scripts/run_all.py --steps eval
# 3) Interfaz web
.venv/Scripts/python.exe -m streamlit run app/app.py
Configurar el LLM
Las respuestas usan DeepSeek V4 Flash. Configura el proveedor/API key en
src/answer.py (LLM_MODEL, LLM_BASE_URL).
Sin clave, el chatbot responde con las secciones recuperadas (sin LLM), útil para depurar.
Cálculos validados (src/calc.py)
Si la pregunta pide un cálculo (p. ej. "calcula la presión de viento para Vz=35 m/s"), el motor lo detecta y usa una fórmula verificada contra el texto de la norma, sin pasar por el LLM. Calculadoras incluidas:
| Cálculo | Fórmula | Fuente |
|---|---|---|
| Presión dinámica de viento | qz = 0.52·Vz² (m/s → Pa) | NTC-Viento 2023, §5.1.3 |
| Presión de diseño por viento | pz = 0.47·Cp·VD² | NTC-Viento 2017/2004, §3.2 |
| Fuerza de arrastre de viento | F = 0.47·CD·VD²·A | NTC-Viento 2017/2004, §3.3 |
| Cortante basal mínimo sísmico | Vo,min = amin·Wo | NTC-Sismo 2023, §7.5 |
| Combinación de cargas | Grupo B: 1.3·CM+1.5·CV · Grupo A: 1.5·CM+1.7·CV | NTC-Criterios 2023, §3.4.1 |
Si faltan datos, el chatbot los pide explícitamente.
Fine-tune del generador (src/finetune_gen.py)
Genera un dataset en formato chat donde cada ejemplo incluye el contexto recuperado (para que el generador aprenda a responder desde el contexto, en vez de memorizar las normas):
.venv/Scripts/python.exe src/finetune_gen.py --max 2000 --top_k 8 --require_all
Filtra automáticamente los ejemplos cuya respuesta "gold" NO está sustentada por el contexto recuperado (numerales citados ausentes → se descartan).
Evaluación
El módulo evaluate.py usa tu dataset de Documents\Fine_Tunning\NTC_CDMX\dataset.jsonl:
para cada pregunta con numerales citados en la respuesta "gold", verifica que el numeral
aparezca entre las secciones recuperadas.
Resultado de referencia (muestra 164 preguntas con cita, top-6): recall@q ≈ 0.58. Aproximadamente 18 % de los numerales citados por el dataset no existen en el corpus de su edición (posibles citas erróneas del dataset o huecos de extracción).
Notas técnicas
- Las ediciones 2004 y 2017 vienen en gacetas (varios documentos por PDF); las
fronteras de cada norma están mapeadas en
src/config.py. - El troceo es por sección numerada (nunca por párrafo), preservando fórmulas/tablas.
- Cada sección lleva metadata
{edición, norma, numeral, página}para citar con precisión. - Los PDFs 2023 tienen nombres con caracteres corruptos en disco; el extractor los resuelve por prefijo numérico.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。