onpe-mcp
MCP server for querying Peruvian electoral data (ONPE) including mesa results, candidate votes, and regional statistics. Enables natural language queries about the 2026 presidential election with local SQLite cache and live API fallback.
README
ONPE MCP
¿Qué es esto? (para quienes no son técnicos)
Imagina que puedes preguntarle a un asistente de IA cosas como:
"¿Cuántos votos sacó Keiko Fujimori en Puno?" "¿Quién ganó en las mesas de Loreto?" "¿Qué pasó en la mesa 900100?" "¿Hubo fraude en las mesas 900K? — es verdad?"
…y recibir una respuesta inmediata con datos reales de la ONPE, sin buscar en PDFs, sin abrir el portal web, sin saber de tecnología.
ONPE MCP es el puente entre un asistente de IA (como Claude o cualquier herramienta compatible con MCP) y los datos oficiales de las elecciones presidenciales del Perú 2026. Tiene las 92,766 mesas de sufragio cargadas localmente y responde en menos de un segundo.
¿Para qué sirve?
| Quiero saber... | Ejemplo de pregunta |
|---|---|
| Resultados de una mesa específica | "dame los resultados de la mesa 900574" |
| Quién ganó en mi región | "top 5 en Puno — quiénes fueron los más votados" |
| Votos de un candidato | "cuántos votos sacó Rafael López Aliaga a nivel nacional" |
| Resultados de peruanos en el exterior | "quién ganó entre los peruanos en Suecia" |
| Legislativo | "quién fue el diputado más votado en Lima" |
| Contexto electoral | "¿qué es el STAE?, ¿puede manipular votos?" |
¿Cómo funciona por dentro? (sin tecnicismos)
- Tú preguntas en lenguaje natural — no necesitas saber códigos ni formatos especiales.
- El asistente entiende qué quieres (una mesa, una región, un candidato…).
- Primero busca en la base de datos local — respuesta en milisegundos, sin internet.
- Si no lo tiene guardado, consulta directamente la ONPE — un poco más lento pero siempre actualizado.
- Si la pregunta es sobre el proceso electoral (fraude, STAE, segunda vuelta…), responde con un compendio de 535 hechos verificados.
La base de datos local se descarga automáticamente la primera vez que arrancas el servidor (~2 minutos). Después de eso, todo es instantáneo.
Servidor MCP para consultas electorales sobre Perú 2026 — primera vuelta presidencial. Expone las 92,766 mesas de sufragio con estrategia cache-first: SQLite local → API ONPE live → compendio cualitativo verificable.
Velocidad: todas las consultas sobre datos locales resuelven en <100 ms. Las consultas que requieren la API ONPE en vivo dependen de la red (~1-8 s).
⚡ Instalación desde cero
# 1. Clonar e instalar
git clone https://github.com/oscarzamora/onpe-mcp
cd onpe-mcp
pip install -e .
# 2. (Opcional pero recomendado) clonar la fuente de datos más actualizada
git clone https://github.com/oscarzamora/onpeescraper ../onpescraper
# 3. Arrancar el servidor MCP
onpe-mcp
La base de datos (data/onpe.db) no se distribuye en el repositorio — se genera localmente en el primer arranque.
🗄️ Hidratación de la base de datos
Al arrancar con la base vacía, el servidor inicia hidratación automática:
WARNING DB vacía al arrancar — hidratación MANDATORIA.
Descargando ATuManera CSV (~92,766 mesas, 1-3 min según red).
INFO Hidratación cold-start completada: 92766 mesas cargadas.
Rutas de hidratación (en orden de prioridad)
| # | Fuente | Cuándo se usa | Tiempo aprox. |
|---|---|---|---|
| 1 | onpescraper local (../onpescraper/output/) |
Si el repo hermano está clonado | 30-60 s |
| 2 | ATuManera CSV (descarga pública desde GitHub) | Fallback automático | 1-3 min |
| 3 | Modo degradado (solo API ONPE live) | Si ambas fallan | inmediato |
Verificar estado de la DB
onpe_health()
DB vacía (arranque en frío):
{
"status": "not_hydrated",
"hydrated": false,
"total_mesas_local": 0,
"next_step": "Llama a onpe_bootstrap_atu_manera() para descargar las 92,766 mesas."
}
DB hidratada y lista:
{
"status": "ok",
"hydrated": true,
"total_mesas_local": 92766,
"total_votos_local": 3801438,
"coverage_pct": 99.9,
"next_step": null
}
Hidratación manual desde el agente
Si la hidratación automática no se completó, llamar directamente:
# Fuente más actualizada — requiere repo onpescraper en ../onpescraper
onpe_bootstrap_snapshot()
# Descarga el CSV público desde GitHub (~100 MB)
onpe_bootstrap_atu_manera()
🏗️ Arquitectura de datos
onpe-mcp/
├── data/
│ ├── onpe.db ← SQLite: mesas, votos, cache, índices pre-computados
│ ├── raw/events.jsonl ← log append-only de cada tool call
│ └── reports/ ← resúmenes markdown diarios
├── src/onpe_mcp/
│ ├── server.py ← tools MCP + NLU/intent routing
│ ├── storage.py ← DataStore: todas las queries SQLite
│ ├── onpe_api.py ← cliente HTTP directo a ONPE
│ ├── gateway.py ← bridge a onpescraper (import dinámico)
│ ├── knowledge_base.py← 535 hechos verificados sobre el proceso
│ └── config.py ← Settings desde variables de entorno
Prioridad de datos en onpe_chat
| Tier | Fuente | Latencia |
|---|---|---|
| 1a | mesa_cache SQLite (JSON API cacheado, TTL 15 min) |
~1 ms |
| 1b | mesas_data + votos SQLite (snapshot hidratado) |
~5 ms |
| 2 | API ONPE live (resultadoelectoral.onpe.gob.pe) |
~1-8 s |
| 3 | Compendio cualitativo (535 hechos verificados) | ~0 ms |
🛠️ Tools MCP
| Tool | Descripción |
|---|---|
onpe_chat |
Interfaz principal — lenguaje natural, cache-first, intención automática |
onpe_get_mesa |
Consulta una mesa por código (cache → live API) |
onpe_get_mesas_batch |
Hasta 200 mesas en paralelo (siempre live) |
onpe_health |
Estado del servidor, DB y cobertura de hidratación |
onpe_bootstrap_snapshot |
Carga snapshot de onpescraper → SQLite |
onpe_bootstrap_atu_manera |
Descarga CSV público → SQLite (~2-5 min) |
onpe_sync_foreign_catalog |
Sincroniza catálogo de países/ciudades para el exterior |
💬 Ejemplos conversacionales
🗳️ Mesa específica
"dame los resultados de la mesa 900100"
Mesa 900100 (IEI 326, Amazonas): Contabilizada.
210 votos emitidos de 248 electores hábiles.
Top: Rafael López Aliaga Cazorla 68v, Keiko Fujimori 55v, Roberto Sánchez 24v.
"cuántos electores hábiles tuvo la mesa 004521 y quién ganó ahí"
"qué estado tiene el acta de la mesa 000001"
📊 Resultados por candidato (nivel nacional)
"cuántos votos sacó Keiko Fujimori a nivel nacional"
Candidato Keiko Sofía Fujimori Higuchi (partido 1) tiene 5,432,109 votos
y posición 1 en el consolidado actual.
"cuántos votos obtuvo Rafael López Aliaga en primera vuelta"
"cuántos votos sacó Roberto Sánchez Palomino"
"quién fue el tercer candidato más votado a nivel nacional"
"qué porcentaje alcanzó Fuerza Popular en 2026"
🗺️ Resultados por región peruana
"top 5 en Puno — quiénes fueron los más votados"
Top 5 en Puno (4,520 mesas · 946,628 votos emitidos)
1. Keiko Sofía Fujimori Higuchi — 197,801 votos (20.9%)
2. Roberto Sánchez Palomino — 178,042 votos (18.8%)
3. Ricardo Belmont Cassinelli — 98,530 votos (10.4%)
4. Carlos Álvarez Requena — 73,914 votos (7.8%)
5. Rafael López Aliaga Cazorla — 59,703 votos (6.3%)
"top 3 en Loreto"
"quién ganó en Cusco en primera vuelta"
"cuántos votos sacó López Aliaga en Arequipa"
"quién fue primero en Ayacucho"
"cuántas mesas tiene Ancash y quién ganó"
"top 3 en Amazonas"
🌎 Exterior
"top 3 de candidatos en Suecia"
"resultados en Estocolmo — quién ganó"
"cuántos votos sacó Keiko Fujimori en Chile"
"quién fue el más votado entre los peruanos en España"
"top 5 candidatos en Argentina"
"cuántos votos hubo en las mesas de Estados Unidos"
🏛️ Legislativo (live API)
"quién fue el diputado más votado en Lima"
"top 10 senadores más votados para Cusco"
"quién ganó los senadores en Arequipa"
"cuántos votos sacó el primer diputado en Piura"
🔍 Segmentos de mesas
"cuántas mesas arrancan en 900 y dónde están"
"top 3 candidatos en las mesas 900K"
"de las mesas que arrancan en 900000, en qué lugares ganó primero López Aliaga"
"cuántos electores hábiles tienen las mesas con prefijo 087"
"cuántas mesas hay en el bloque 150 y qué candidato ganó ahí"
❓ Contexto y proceso electoral
"las mesas 900K son fantasma — es verdad?"
"por qué algunas mesas tienen solo 50 votantes"
"hubo fraude en las elecciones 2026"
"qué es el STAE y puede manipular votos"
"por qué hubo mesas que votaron el lunes 13 de abril"
"cuándo es la segunda vuelta"
"quién pasó a segunda vuelta"
"por qué el sur del Perú vota diferente al norte"
⚙️ Configuración
Copia .env.example a .env para ajustar valores:
| Variable | Default | Descripción |
|---|---|---|
ONPE_SCRAPER_ROOT |
../onpescraper |
Ruta al repo onpescraper |
ONPE_SCRAPER_REPO_URL |
https://github.com/oscarzamora/onpeescraper |
URL a clonar si no existe |
ONPE_DATA_DIR |
./data |
Directorio de la base SQLite y eventos |
ONPE_BOOTSTRAP_ON_STARTUP |
true |
Refresca desde onpescraper al arrancar (si ya hay datos) |
ONPE_BOOTSTRAP_INCLUDE_VOTES |
true |
Incluye votos en el snapshot |
ONPE_ATU_MANERA_BOOTSTRAP |
false |
Fuerza descarga ATuManera al inicio |
ONPE_MAX_BATCH_SIZE |
200 |
Límite de lote en onpe_get_mesas_batch |
ONPE_CACHE_TTL_SECONDS |
900 |
TTL del cache individual de mesa (segundos) |
ONPE_AUTO_SYNC_FOREIGN_CATALOG_ON_DEMAND |
true |
Sincroniza catálogo extranjero si no hay datos |
Requisitos
- Python 3.11+
- Git (para clonar onpescraper — opcional si usas
onpe_bootstrap_atu_manera)
📐 Contrato ONPE
- Especificación técnica:
docs/onpe-api-contract.md - JSON schema response:
schemas/onpe.actas.buscar.mesa.response.schema.json - JSON schema acta mínima:
schemas/onpe.acta.min.schema.json
推荐服务器
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 模型以安全和受控的方式获取实时的网络信息。