initial commit

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-10-09 03:06:19 +02:00
commit 13c2298ac0
Se han modificado 20 ficheros con 6112 adiciones y 0 borrados

13
.gitignore vendido Archivo normal
Ver fichero

@@ -0,0 +1,13 @@
node_modules/
dist/
*.log
*.tgz
.env
.DS_Store
*.swp
*.swo
*~
.vscode/
.idea/
coverage/
.nyc_output/

258
AI_TOOLKIT_SETUP.md Archivo normal
Ver fichero

@@ -0,0 +1,258 @@
# Configuración para VS Code AI Toolkit
## Cómo Configurar el Servidor MCP INE en AI Toolkit
### Opción 1: HTTP JSON-RPC (Recomendado) 🎯
1. **Inicia el servidor MCP INE**:
```bash
cd /home/ale/projects/mcp/mcp-ine
npm start
```
2. **Abre VS Code AI Toolkit**:
- Presiona `Ctrl+Shift+P` (o `Cmd+Shift+P` en Mac)
- Busca: **"AI Toolkit: Configure MCP Servers"**
3. **Agrega esta configuración**:
```json
{
"mcpServers": {
"ine-spain": {
"url": "http://localhost:3000/mcp/v1",
"transport": "http",
"description": "API del Instituto Nacional de Estadística (INE) de España - 24 herramientas para consultar datos estadísticos"
}
}
}
```
4. **Reinicia AI Toolkit** y verifica que aparezca "ine-spain" con 24 herramientas
### Opción 2: Server-Sent Events (SSE)
1. **Inicia el servidor SSE**:
```bash
cd /home/ale/projects/mcp/mcp-ine
npm run start:sse
```
2. **Configuración en AI Toolkit**:
```json
{
"mcpServers": {
"ine-spain-sse": {
"url": "http://localhost:3001/sse",
"transport": "sse",
"description": "API INE España via SSE"
}
}
}
```
### Opción 3: stdio (Comunicación Directa)
Esta opción NO requiere iniciar el servidor manualmente.
**Configuración en AI Toolkit**:
```json
{
"mcpServers": {
"ine-spain-stdio": {
"command": "node",
"args": [
"dist/index.js",
"--stdio"
],
"cwd": "/home/ale/projects/mcp/mcp-ine",
"description": "API INE España via stdio",
"env": {}
}
}
}
```
## Verificar que Funciona
### 1. Verifica el Estado del Servidor (HTTP/SSE)
```bash
# Para HTTP (puerto 3000)
curl http://localhost:3000/health
# Para SSE (puerto 3001)
curl http://localhost:3001/health
```
Respuesta esperada:
```json
{
"status": "ok",
"timestamp": "2025-10-09T01:02:33.658Z",
"service": "MCP INE Server"
}
```
### 2. Lista las Herramientas Disponibles
```bash
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}' \
| python3 -m json.tool | grep '"name"' | wc -l
```
Debe devolver: **24** (número de herramientas)
### 3. Prueba una Consulta Real
```bash
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"tools/call",
"params":{
"name":"ine_datos_serie",
"arguments":{
"idSerie":"IPC251856",
"nult":1,
"tip":"A"
}
},
"id":1
}' | python3 -m json.tool
```
## Ejemplos de Consultas en AI Toolkit
Una vez configurado, puedes hacer estas preguntas en el chat:
### Consultas Básicas
```
¿Cuál es el último valor del IPC en España?
Dame los últimos 12 meses del IPC
¿Qué operaciones estadísticas tiene disponibles el INE?
```
### Consultas Específicas
```
Obtén los datos de la tabla 50902 de los últimos 5 períodos
¿Qué variables tiene la operación IPC?
Lista las series de la operación EPA (Encuesta de Población Activa)
```
### Consultas con Filtros
```
Busca datos del IPC para Madrid (provincia 29) con variación mensual
Dame los grupos ECOICOP disponibles para el IPC
¿Cuáles son las provincias de Andalucía en los datos del INE?
```
### Consultas de Metadatos
```
¿Qué periodicidades están disponibles en el INE?
Lista las publicaciones de la operación IPC
Dame información detallada sobre la operación del IPC
```
## Solución de Problemas
### El servidor no aparece en AI Toolkit
1. Verifica que el servidor esté corriendo:
```bash
curl http://localhost:3000/health
```
2. Si no responde, inicia el servidor:
```bash
cd /home/ale/projects/mcp/mcp-ine
npm start
```
3. Reinicia VS Code completamente
4. Verifica la configuración JSON (sin errores de sintaxis)
### Error "Cannot connect to MCP server"
1. Comprueba que no haya otro proceso usando el puerto:
```bash
netstat -tuln | grep 3000
```
2. Si hay otro proceso, mátalo o cambia el puerto:
```bash
PORT=3005 npm start
```
Y actualiza la URL en la configuración:
```json
"url": "http://localhost:3005/mcp/v1"
```
### El servidor se cierra solo
Ejecuta el servidor en modo background o en una terminal separada:
```bash
# Terminal 1: Servidor
cd /home/ale/projects/mcp/mcp-ine
npm start
# Terminal 2: VS Code
code .
```
O usa `nohup`:
```bash
nohup npm start > server.log 2>&1 &
```
### Las herramientas no aparecen
1. Verifica que la URL sea correcta (debe terminar en `/mcp/v1`)
2. Verifica que el servidor responda:
```bash
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'
```
3. Revisa los logs del servidor en la terminal
### Error de certificados SSL (si usas HTTPS)
Para desarrollo local, usa HTTP (no HTTPS):
```json
"url": "http://localhost:3000/mcp/v1"
```
## Documentación Adicional
- **Swagger UI**: http://localhost:3000/api-docs
- **README completo**: `/home/ale/projects/mcp/mcp-ine/README.md`
- **Guía rápida**: `/home/ale/projects/mcp/mcp-ine/QUICKSTART.md`
- **API INE oficial**: https://www.ine.es/dyngs/DataLab/manual.html?cid=45
## Contacto y Soporte
- **GitHub Issues**: Para reportar problemas
- **Documentación**: Ver README.md y QUICKSTART.md
- **API INE**: https://www.ine.es
---
💡 **Consejo**: Mantén el servidor corriendo en una terminal separada mientras usas AI Toolkit para evitar interrupciones.

659
API.txt Archivo normal
Ver fichero

@@ -0,0 +1,659 @@
Referencia de la API
Se accede a la información disponible en INEbase mediante peticiones URL. Las peticiones URL tienen la siguiente estructura:
https://servicios.ine.es/wstempus/js/{idioma}/{función}/{input}[?parámetros]
Los campos que aparecen entre llaves, { }, son obligatorios. Los campos que aparecen entre corchetes, [ ], son opcionales y cambian en relación a la función considerada.
{idioma}. Puede tomar los siguientes valores:
ES: español.
EN: inglés.
{función}. Funciones implementadas en el sistema para poder realizar diferentes tipos de consulta.
{input}. Identificadores de los elementos de entrada de las funciones. Estos inputs varían en base a la función utilizada.
[¿parámetros]. Los parámetros en la URL se establecen a partir del símbolo ?. Cuando haya más de un parámetro, el símbolo & se utiliza como separador. No todas las funciones admiten todos los parámetros posibles.
Lista de funciones
DATOS_TABLA
Obtener datos para una tabla específica.
Input
Código identificativo de la tabla. Para obtener el código de una tabla acceder a Obtención del identificador de una tabla utilizando INEbase.
Parámetros
nult: devolver los n últimos datos o periodos.
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿)¿.
tv: parámetro para filtrar, utilizado con el formato tv=id_variable:id_valor. Más información en Como filtrar datos de una tabla.
date:Obtener los datos entre dos fechas. El formato es date=aaaammdd:aaaammdd
Salida
Información y datos de las series contenidas en la tabla: nombre de la serie, identificador Tempu3 de la unidad, identificador Tempus3 de la escala, fecha, identificador Tempus3 del tipo de dato, identificador Tempus3 del periodo, año y valor (dato).
Ejemplos
Devuelve todos los periodos de la tabla con Id=50902
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902
Devuelve el último periodo de la tabla con Id=50902
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=1
Devuelve los últimos 5 periodos de la tabla con Id=50902
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=5
Devuelve el último periodo de la tabla con Id=50902 más salida amigable
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=1&tip=A
Devuelve el último periodo de la tabla con Id=50902 junto a los metadatos
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=1&tip=M
Devuelve el último periodo de la tabla con Id=50902 con salida amigable y metadatos
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=1&tip=AM
Devuelve el último periodo de la tabla con Id=50902 y nivel de detalle 2
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?nult=1&det=2
Devuelve los datos entre el 01/01/2024 y el 31/12/2024
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?date=20240101:20241231
Devuelve los datos a partir del 01/01/2025
https://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/50902?date=20250101:
DATOS_SERIE
Obtener datos para una serie específica.
Input
Código identificativo de la serie. Para obtener el código de una serie acceder a Obtención del identificador de una serie utilizando INEbase.
Parámetros
nult: devolver los n últimos datos o periodos.
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿)¿.
date: obtener los datos entre dos fechas. El formato es date=aaaammdd:aaaammdd.
Salida
Información de la serie: nombre de la serie, identificador Tempu3 de la unidad, identificador Tempus3 de la escala, fecha, identificador Tempus3 del tipo de dato, identificador Tempus3 del periodo, año y valor (dato).
Ejemplos
Devuelve el último periodo de la serie con código IPC251856
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?nult=1
Devuelve los últimos 5 periodos de la serie con código IPC251856
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?nult=5
Devuelve el último periodo de la serie con código IPC251856 con salida amigable y metadatos
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?nult=1&tip=AM
Devuelve el último periodo de la serie con código IPC251856 y nivel de detalle 2
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?nult=1&det=2
Devuelve los datos entre el 01/01/2023 y el 31/12/2023
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?date=20230101:20231231&tip=A
Devuelve los datos a partir del 01/01/2024
https://servicios.ine.es/wstempus/js/ES/DATOS_SERIE/IPC251856?date=20240101:&tip=A
DATOS_METADATAOPERACION
Obtener datos de series pertenecientes a una operación dada utilizando un filtro.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
p: id de la periodicidad de las series. Periodicidades comunes: 1 (mensual), 3 (trimestral), 6 (semestral), 12 (anual). Para ver una lista de las periodicidades acceder a PERIODICIDADES.
nult: devolver los n últimos datos o periodos.
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿).
g1: primer filtro de variables y valores. El formato es g1=id_variable_1:id_valor_1. Cuando no se especifica el id_valor_1 se devuelven todos los valores de id_variable_1 (g1=id_variable_1:). Para obtener las variables de una operación dada consultar https://servicios.ine.es/wstempus/js/ES/VARIABLES_OPERACION/IPC. Para obtener los valores de una variable específica de una operación data consultar https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLEOPERACION/762/IPC.
g2: segundo filtro de variables y valores. El formato es g2=id_variable_2:id_valor_2. Cuando no se especifica el id_valor_2 se devuelven todos los valores de id_variable_2 (g2=id_variable_2:). Seguiríamos con g3, g4,¿ según el número de filtros que se utilicen sobre variables.
Ejemplos
Devuelve el último periodo de las series de la operación del IPC referentes a la provincia de Madrid (g1=115:29) para la variación mensual (g2=3:84) y todos los grupos ECOICOP (g3=762:)
https://servicios.ine.es/wstempus/js/ES/DATOS_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&nult=1
Devuelve los últimos 5 periodos de las series de la operación del IPC referentes a la provincia de Madrid (g1=115:29) para la variación mensual (g2=3:84) y todos los grupos ECOICOP (g3=762:)
https://servicios.ine.es/wstempus/js/ES/DATOS_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&nult=5
Consulta con salida amigable y metadatos
https://servicios.ine.es/wstempus/js/ES/DATOS_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&nult=1&tip=AM
Consulta con nivel de detalle 2
https://servicios.ine.es/wstempus/js/ES/DATOS_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&nult=1&det=2
OPERACIONES_DISPONIBLES
Obtener todas las operaciones disponibles.
Input
Ninguno.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
geo: para obtener resultados en función del ámbito geográfico:
geo=1: resultados por comunidades autónomas, provincias, municipios y otras desagregaciones.
geo=0: resultados nacionales.
page: la respuesta está paginada. Se ofrece un máximo de 500 elementos por página para no ralentizar la respuesta. Para consultar las páginas siguientes, se utiliza el parámetro page.
Salida
Se obtienen los identificadores del elemento operación estadística. Existen tres códigos para la identificación de la operación estadística "Índice de Precios de Consumo (IPC)":
código numérico Tempus3 interno (Id=25).
código de la operación estadística en el Inventario de Operaciones Estadísticas (IOE30138).
código alfabético Tempus3 interno (IPC).
Ejemplos
Devuelve las operaciones disponibles
https://servicios.ine.es/wstempus/js/ES/OPERACIONES_DISPONIBLES
Devuelve todas las operaciones disponibles y nivel de detalle 2
https://servicios.ine.es/wstempus/js/ES/OPERACIONES_DISPONIBLES?det=2
Devuelve todas las operaciones disponibles que contengan desagregación geográfica (comunidades autónomas, provincias, municipios y otras desagregaciones)
https://servicios.ine.es/wstempus/js/ES/OPERACIONES_DISPONIBLES?geo=1
Devuelve todas las operaciones disponibles que contengan solamente resultados nacionales
https://servicios.ine.es/wstempus/js/ES/OPERACIONES_DISPONIBLES?geo=0
Devuelve las operaciones disponibles (primeros 500 resultados)
https://servicios.ine.es/wstempus/js/ES/OPERACIONES_DISPONIBLES?page=1
OPERACION
Obtener una operación.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
Salida
Información de la operación estadística IPC: identificador Tempus3, código del IOE y nombre de la operación. Existen tres códigos para la identificación de la operación estadística "Índice de Precios de Consumo (IPC)":
código numérico Tempus3 interno (Id=25).
código de la operación estadística en el Inventario de Operaciones Estadísticas (IOE30138).
código alfabético Tempus3 interno (IPC).
Ejemplos
Devuelve la operación IPC utilizando el código alfabético Tempus3 interno (IPC)
https://servicios.ine.es/wstempus/js/ES/OPERACION/IPC
Devuelve la operación IPC utilizando el identificador interno Tempus 3 (id=25)
https://servicios.ine.es/wstempus/js/ES/OPERACION/25
Devuelve la operación IPC utilizando el código de la operación estadística en el Inventario de Operaciones Estadísticas (IOE30138)
https://servicios.ine.es/wstempus/js/ES/OPERACION/IOE30138
Devuelve la operación IPC y nivel de detalle 2
https://servicios.ine.es/wstempus/js/ES/OPERACION/IPC?det=2
VARIABLES
Obtener todas las variables disponibles.
Input
Ninguno.
Parámetros
page: la respuesta está paginada. Se ofrece un máximo de 500 elementos por página para no ralentizar la respuesta. Para consultar las páginas siguientes, se utiliza el parámetro page.
Salida
Información de todas las variables del Sistema: identificador Tempus3, nombre de la variable y código oficial.
Ejemplos
Devuelve las variables disponibles (primeros 500 resultados)
https://servicios.ine.es/wstempus/js/ES/VARIABLES
Devuelve las variables disponibles (segundos 500 resultados)
https://servicios.ine.es/wstempus/js/ES/VARIABLES?page=2
VARIABLES_OPERACION
Obtener todas las variables utilizadas en una operación dada.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
page: la respuesta está paginada. Se ofrece un máximo de 500 elementos por página para no ralentizar la respuesta. Para consultar las páginas siguientes, se utiliza el parámetro page.
Salida
Información de las variables que describen la operación: identificador Tempus3, nombre de la variable y código oficial.
Ejemplos
Devuelve las variables de la operación IPC
https://servicios.ine.es/wstempus/js/ES/VARIABLES_OPERACION/IPC
Devuelve las variables de la operación IPC (primeros 500 resultados). Consulta igual a la anterior
https://servicios.ine.es/wstempus/js/ES/VARIABLES_OPERACION/IPC?page=1
VALORES_VARIABLE
Obtener todos los valores para una variable específica.
Input
Código identificador de la variable. Para consultar las variables disponibles acceder a VARIABLES.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
clasif: Obtener valores para una determinada clasificación. Para consultar las clasificaciones vea CLASIFICACIONES.
Salida
Información de los valores que puede tomar la variable: identificador Tempus3 del valor, identificador Tempus 3 de la variable a la que pertenece, nombre del valor y código oficial.
Ejemplos
Devuelve los valores de la variable Provincias (Id=115)
https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLE/115
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLE/115?det=2
Consulta de municipios de 2019
https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLE/19?&clasif=107
VALORES_VARIABLEOPERACION
Obtener todos los valores para una variable específica de una operación dada.
Input
Códigos identificadores de la variable y de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES y para consultar las variables disponibles acceder a VARIABLES_OPERACION.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
Salida
Información de los valores que puede tomar la variable para describir la operación: identificador Tempus3 del valor, objeto variable Tempus3 a la que pertenece, nombre del valor y código oficial.
Ejemplos
Valores de la variable "Grupos ECOICOP" (Id=762) para la operación IPC (IOE30138 / IPC / 25).
https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLEOPERACION/762/25
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLEOPERACION/762/25?det=2
TABLAS_OPERACION
Obtener un listado de todas las tablas de una operación.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
geo: para obtener resultados en función del ámbito geográfico.
geo=1: resultados por comunidades autónomas, provincias, municipios y otras desagregaciones.
geo=0: Resultados nacionales.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿).
Salida
Información de las tablas asociadas a la operación: identificador Tempus3 de la tabla, nombre de la tabla, código con información del nivel geográfico y clasificación, objeto Tempus3 periodicidad, objeto Tempus3 publicación, objeto Tempus3 periodo inicio, año inicio, PubFechaAct dentro de la publicación , FechaRef_fin y última modificación.
FechaRef_fin: nulo cuando el último periodo publicado coincide con el de la publicación fecha, en otro caso, cuando la tabla está cortada en un periodo anterior al de la publicación fecha, es sustituido por Fk_perido_fin/ Anyo_perido_fin (fecha del último dato publicado). Consultar https://servicios.ine.es/wstempus/js/ES/TABLAS_OPERACION/33.
PubFechaAct = contiene la última fecha de actualización de la tabla y el último periodo-año publicado.
Ejemplos
Tablas estadísticas asociadas a la operación estadística IPC (IOE30138 / IPC / 25)
https://servicios.ine.es/wstempus/js/ES/TABLAS_OPERACION/IPC
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/TABLAS_OPERACION/IPC?det=2
Salida amigable
https://servicios.ine.es/wstempus/js/ES/TABLAS_OPERACION/IPC?det=2&tip=A
Tablas con contenido geográfico
https://servicios.ine.es/wstempus/js/ES/TABLAS_OPERACION/IPC?geo=1
GRUPOS_TABLA
Obtener todos los grupos para una tabla específica. Una tabla está definida por diferentes grupos o combos de selección y cada uno de ellos por los valores que toman una o varias variables.
Input
Código identificativo de la tabla. Para obtener el código de una tabla acceder a Obtención del identificador de una tabla utilizando INEbase.
Parámetros
Ninguno.
Salida
Grupos de valores que definen la tabla: identificador Tempus3 del grupo y nombre del grupo.
Ejemplos
Grupos o combos de selección que definen a la tabla Índices por comunidades autónomas: general y de grupos ECOICOP (Id 50913)
https://servicios.ine.es/wstempus/js/ES/GRUPOS_TABLA/50913
VALORES_GRUPOSTABLA
Obtener todos los valores de un grupo específico para una tabla dada. Una tabla está definida por diferentes grupos o combos de selección y cada uno de ellos por los valores que toman una o varias variables.
Input
Códigos identificativos de la tabla y del grupo. Para consultar los grupos de una tabla acceder a GRUPOS_TABLA.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
Salida
Información de los valores pertenecientes al grupo: identificador Tempus3 del valor, identificador Tempus 3 de la variable a la que pertenece, nombre del valor y código oficial.
Ejemplos
Valores del grupo "Comunidades y Ciudades Autónomas" (Id=110924) perteneciente a la tabla tabla Índices por comunidades autónomas: general y de grupos ECOICOP (Id 50913)
https://servicios.ine.es/wstempus/js/ES/VALORES_GRUPOSTABLA/50913/110924
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/VALORES_GRUPOSTABLA/50913/110924?det=2
SERIE
Obtener una serie específica.
Input
Código identificativo de la serie. Para obtener el código de una serie acceder a Obtención del identificador de una serie utilizando INEbase.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿).
Salida
Información de la serie: identificadores Tempus3 de la serie, objeto Tempus3 operación, nombre de la serie, número de decimales que se van a visualizar para los datos de esa serie, objeto Tempus3 periodicidad, objeto Tempus3 publicación, PubFechaAct dentro de la publicación, objeto Tempsu3 clasificación, objeto Tempus3 escala y objeto Tempus3 unidad.
PubFechaAct = contiene la última fecha de actualización de la serie y el último periodo-año publicado.
clasificación = nos da información de la versión temporal de la serie, por ejemplo, la clasificación nacional que en algunos casos sigue, marco poblacional, base utilizada en el cálculo de los índices,...
Ejemplos
Consulta de la serie IPC251852 que recoge la variación mensual del Índice de precios de consumo
https://servicios.ine.es/wstempus/js/ES/SERIE/IPC251852
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/SERIE/IPC251852?det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/js/ES/SERIE/IPC251852?det=2&tip=A
Consulta con metadatos y salida amigable
https://servicios.ine.es/wstempus/js/ES/SERIE/IPC251852?tip=AM
SERIES_OPERACION
Obtener todas las series de una operación.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿).
page: la respuesta está paginada. Se ofrece un máximo de 500 elementos por página para no ralentizar la respuesta. Para consultar las páginas siguientes, se utiliza el parámetro page.
Salida
Información de las series: identificadores Tempus3 de la serie, identificador Tempus3 de la operación, nombre de la serie, número de decimales que se van a visualizar para los datos de esa serie, identificador Tempus3 de la periodicidad, identificador Tempus3 de la publicación, identificador Tempsu3 de la clasificación, identificador Tempus3 de la escala e identificador Tempus3 de la unidad.
Ejemplos
Consulta de las primeras 500 series pertenecientes a la operación IPC (IOE30138 / IPC / 25)
https://servicios.ine.es/wstempus/js/ES/SERIES_OPERACION/IPC?page=1
Consulta de las segundas 500 series pertenecientes a la operación IPC (IOE30138 / IPC / 25)
https://servicios.ine.es/wstempus/js/ES/SERIES_OPERACION/IPC?page=2
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/SERIES_OPERACION/IPC?page=1&det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/js/ES/SERIES_OPERACION/IPC?page=1&det=2&tip=A
Consulta con metadatos y salida amigable
https://servicios.ine.es/wstempus/js/ES/SERIES_OPERACION/IPC?page=1&tip=AM
VALORES_SERIE
Obtener los valores y variables que definen una serie.
Input
Código identificativo de la serie. Para obtener el código de una serie acceder a Obtención del identificador de una serie utilizando INEbase.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
Salida
Información de los metadatos que definen a la serie: identificador Tempus3 del valor, identificador Tempus3 de la variable a la que pertenece, nombre del valor y código oficial del valor.
Ejemplos
Consulta de las variables y valores de la serie que recoge los datos del índice general el IPC (IPC251852)
https://servicios.ine.es/wstempus/js/ES/VALORES_SERIE/IPC251852
Consulta con nivel de detalle
https://servicios.ine.es/wstempus/js/ES/VALORES_SERIE/IPC251852?det=1
SERIES_TABLA
Obtener todas las series de una tabla específica.
Input
Código identificativo de la tabla. Para obtener el código de una tabla acceder a Obtención del identificador de una tabla utilizando INEbase.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿).
tv: parámetro para filtrar, utilizado con el formato tv=id_variable:id_valor. Más información en Como filtrar datos de una tabla.
Salida
Información de las series de la tabla: identificadores Tempus3 de la serie, identificador Tempus3 de la operación, nombre de la serie, número de decimales que se van a visualizar para los datos de esa serie, identificador Tempus3 de la periodicidad, identificador Tempus3 de la publicación, identificador Tempsu3 de la clasificación, identificador Tempus3 de la escala e identificador Tempus3 de la unidad.
Ejemplos
Series que aparecen en la tabla Índices por comunidades autónomas: general y de grupos ECOICOP de la operación IPC (Id 50913)
https://servicios.ine.es/wstempus/jsCache/ES/SERIES_TABLA/50913
Consulta con nivel de detalle máximo
https://servicios.ine.es/wstempus/jsCache/ES/SERIES_TABLA/50913?det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/jsCache/ES/SERIES_TABLA/50913?det=2&tip=A
Consulta de metadatos y salida amigable
https://servicios.ine.es/wstempus/jsCache/ES/SERIES_TABLA/50913?tip=AM
SERIE_METADATAOPERACION
Obtener series pertenecientes a una operación dada utilizando un filtro.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
p: id de la periodicidad de las series. Periodicidades comunes: 1 (mensual), 3 (trimestral), 6 (semestral), 12 (anual). Para ver una lista de las periodicidades acceder a PERIODICIDADES.
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿), incluir metadatos (`M¿) o ambos (`AM¿).
g1: primer filtro de variables y valores. El formato es g1=id_variable_1:id_valor_1. Cuando no se especifica el id_valor_1 se devuelven todos los valores de id_variable_1 (g1=id_variable_1:). Para obtener las variables de una operación dada consultar https://servicios.ine.es/wstempus/js/ES/VARIABLES_OPERACION/IPC. Para obtener los valores de una variable específica de una operación data consultar https://servicios.ine.es/wstempus/js/ES/VALORES_VARIABLEOPERACION/762/IPC.
g2: segundo filtro de variables y valores. El formato es g2=id_variable_2:id_valor_2. Cuando no se especifica el id_valor_2 se devuelven todos los valores de id_variable_2 (g2=id_variable_2:). Seguiríamos con g3, g4,¿ según el número de filtros que se utilicen sobre variables.
Salida
Información de las series cuya definición de metadatos cumple los criterios establecidos: identificadores Tempus3 de la serie, identificador Tempus3 de la operación, nombre de la serie, número de decimales que se van a visualizar para los datos de esa serie, identificador Tempus3 de la periodicidad, identificador Tempus3 de la publicación, identificador Tempsu3 de la clasificación, identificador Tempus3 de la escala e identificador Tempus3 de la unidad.
Ejemplos
Devuelve la definición de las series de la operación del IPC referentes a la provincia de Madrid (g1=115:29) para la variación mensual (g2=3:84) y todos los grupos ECOICOP (g3=762:)
https://servicios.ine.es/wstempus/js/ES/SERIE_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1
Consulta con nivel de detalle máximo
https://servicios.ine.es/wstempus/js/ES/SERIE_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&det=2
https://servicios.ine.es/wstempus/js/ES/SERIE_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&det=2&tip=A
Consulta con metadatos y salida amigable
https://servicios.ine.es/wstempus/js/ES/SERIE_METADATAOPERACION/IPC?g1=115:29&g2=3:84&g3=762:&p=1&tip=AM
PERIODICIDADES
Obtener las periodicidades disponibles.
Input
Ninguno.
Parámetros
Ninguno.
Salida
Información de las periodicidades disponibles: identificador Tempus3 de la periodicidad, nombre y código.
Ejemplos
Devuelve todas las periodicidades
https://servicios.ine.es/wstempus/js/ES/PERIODICIDADES
PUBLICACIONES
Obtener las publicaciones disponibles.
Input
Ninguno.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿).
Salida
Información de todas las publicaciones: identificador Tempus3 de la publicación, nombre, identificador Tempus3 de la periodicidad e identificador Tempus3 de la publicación fecha.
Ejemplos
Devuelve todas las publicaciones
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES?det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES?det=2&tip=A
PUBLICACIONES_OPERACION
Obtener todas las publicaciones para una operación dada.
Input
Código identificativo de la operación. Para consultar las operaciones disponibles acceder a OPERACIONES_DISPONIBLES.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿).
Salida
Información de todas las publicaciones de una operación: identificador Tempus3 de la publicación, nombre, identificador Tempus3 de la periodicidad e identificador Tempus3 de la publicación fecha.
Ejemplos
Devuelve todas las publicaciones de la operación del IPC (IOE30138 / IPC / 25)
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES_OPERACION/IPC
Consulta con nivel máximo de detalle
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES_OPERACION/IPC?det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONES_OPERACION/IPC?det=2&tip=A
PUBLICACIONFECHA_PUBLICACION
Obtener las fechas de publicación para una publicación dada.
Input
Código identificativo de la publicación. Para obtener una lista de las publicaciones acceder a PUBLICACIONES o PUBLICACIONES_OPERACION.
Parámetros
det: ofrece mayor nivel de detalle de la información mostrada. Valores válidos son 0, 1 y 2.
tip: obtener la respuesta de las peticiones de modo más amigable (`A¿).
Salida
Información de todas las publicaciones de una operación: identificador Tempus3 de la publicación, nombre, identificador Tempus3 de la periodicidad e identificador Tempus3 de la publicación fecha.
Ejemplos
Obtener las fechas de la publicación "Índice de Precios de Consumo" (Id=8)
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONFECHA_PUBLICACION/8
Consulta con máximo nivel de detalle
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONFECHA_PUBLICACION/8?det=2
Consulta con salida amigable
https://servicios.ine.es/wstempus/js/ES/PUBLICACIONFECHA_PUBLICACION/8?tip=A
CLASIFICACIONES
Obtener todas las clasificaciones disponibles.
Input
Ninguno
Parámetros
Ninguno
Salida
Información de todas las clasificaciones del Sistema: identificador Tempus3, nombre de la clasificación y fecha.
Ejemplos
Devuelve las clasificaciones disponibles
https://servicios.ine.es/wstempus/js/ES/CLASIFICACIONES
CLASIFICACIONES_OPERACION
Obtener todas las clasificaciones de una operación dada
Input
Código identificador de la operación. Para consultar las operaciones disponibles vea OPERACIONES_DISPONIBLES.
Parámetros
Ninguno
Salida
Información de las clasificaciones de una operación: identificador Tempus3, nombre de la clasificación y fecha.
Ejemplos
Clasificaciones para la operación IPC (IOE30138 / IPC / 25).
https://servicios.ine.es/wstempus/js/ES/CLASIFICACIONES_OPERACION/25
VALORES_HIJOS
Obtener los valores hijo de un valor padre dado dentro de una estructura jerárquica.
Input
Códigos identificadores de la variable y del valor. Para consultar las variables disponibles vea VARIABLES y para consultar los valores de una variable vea VALORES_VARIABLE.
Parámetros
det: Ofrece mayor nivel de detalle de la información mostrada. Valores válidos del parámetro: 0, 1 y 2
Salida
Información de los valores hijo de un valor dentro de una estructura jerárquica: identificador Tempus3 del valor, objeto variable Tempus3 a la que pertenece, nombre del valor y código oficial, identificadores de valores padre.
Ejemplos
Provincias (hijos de Comunidades Autónomas) de Andalucía (variable 70 e Id=8997)
https://servicios.ine.es/wstempus/js/ES/VALORES_HIJOS/70/8997
Misma consulta pero con mas detalle de salida
https://servicios.ine.es/wstempus/js/ES/VALORES_HIJOS/70/8997?det=2

21
LICENSE Archivo normal
Ver fichero

@@ -0,0 +1,21 @@
# Licencia MIT
Copyright (c) 2025 MCP INE Server
Se concede permiso, de forma gratuita, a cualquier persona que obtenga una copia
de este software y de los archivos de documentación asociados (el "Software"),
para utilizar el Software sin restricción, incluyendo sin limitación los derechos
a usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar, y/o vender
copias del Software, y a permitir a las personas a las que se les proporcione el
Software a hacer lo mismo, sujeto a las siguientes condiciones:
El aviso de copyright anterior y este aviso de permiso se incluirán en todas las
copias o partes sustanciales del Software.
EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O
IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A GARANTÍAS DE COMERCIALIZACIÓN, IDONEIDAD
PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O
TITULARES DEL COPYRIGHT SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑOS U OTRAS
RESPONSABILIDADES, YA SEA EN UNA ACCIÓN DE CONTRATO, AGRAVIO O CUALQUIER OTRO
MOTIVO, QUE SURJA DE O EN CONEXIÓN CON EL SOFTWARE O EL USO U OTRO TIPO DE
ACCIONES EN EL SOFTWARE.

234
PROJECT_SUMMARY.md Archivo normal
Ver fichero

@@ -0,0 +1,234 @@
# MCP INE Server - Resumen del Proyecto
## ✅ Implementación Completa
### 📁 Estructura del Proyecto
```
mcp-ine/
├── src/
│ ├── index.ts # Servidor principal HTTP JSON-RPC
│ ├── server-sse.ts # Servidor SSE (Server-Sent Events)
│ ├── swagger.ts # Especificación OpenAPI/Swagger
│ ├── examples.ts # Ejemplos de uso
│ ├── types/
│ │ └── ine.types.ts # Definiciones TypeScript completas
│ └── services/
│ └── ine-client.ts # Cliente HTTP para API INE (24 endpoints)
├── dist/ # Código JavaScript compilado
├── package.json # Dependencias y scripts npm
├── tsconfig.json # Configuración TypeScript
├── mcp-config.json # Configuración para AI Toolkit
├── install.sh # Script de instalación
├── start-server.sh # Iniciar servidor HTTP
├── start-sse.sh # Iniciar servidor SSE
├── README.md # Documentación completa
├── QUICKSTART.md # Guía rápida de inicio
├── .gitignore # Archivos a ignorar en git
└── API.txt # Referencia original de la API INE
```
### 🎯 Características Implementadas
#### 1. **24 Herramientas MCP** (Todas las funciones de la API INE)
**Datos Estadísticos:**
-`ine_datos_tabla` - Datos de tablas
-`ine_datos_serie` - Datos de series temporales
-`ine_datos_metadata_operacion` - Datos con filtros de metadata
**Operaciones:**
-`ine_operaciones_disponibles` - Lista de operaciones
-`ine_operacion` - Info de operación específica
**Variables y Valores:**
-`ine_variables` - Todas las variables
-`ine_variables_operacion` - Variables por operación
-`ine_valores_variable` - Valores de variable
-`ine_valores_variable_operacion` - Valores en operación
-`ine_valores_hijos` - Valores jerárquicos
**Series Temporales:**
-`ine_serie` - Info de serie
-`ine_series_operacion` - Series de operación
-`ine_series_tabla` - Series de tabla
-`ine_serie_metadata_operacion` - Búsqueda con filtros
-`ine_valores_serie` - Variables de serie
**Tablas:**
-`ine_tablas_operacion` - Tablas de operación
-`ine_grupos_tabla` - Grupos de tabla
-`ine_valores_grupos_tabla` - Valores de grupos
**Metadatos:**
-`ine_periodicidades` - Periodicidades disponibles
-`ine_publicaciones` - Publicaciones
-`ine_publicaciones_operacion` - Publicaciones de operación
-`ine_publicacion_fecha_publicacion` - Fechas de publicación
-`ine_clasificaciones` - Clasificaciones
-`ine_clasificaciones_operacion` - Clasificaciones de operación
#### 2. **Tres Modos de Transporte**
-**HTTP JSON-RPC** (puerto 3000) - Principal, recomendado para AI Toolkit
-**SSE** (puerto 3001) - Server-Sent Events para streaming
-**stdio** - Comunicación directa stdin/stdout
#### 3. **Documentación Swagger/OpenAPI**
- ✅ Especificación OpenAPI 3.0 completa
- ✅ Swagger UI interactivo en `/api-docs`
- ✅ Documentación de todos los endpoints
- ✅ Ejemplos de uso incluidos
#### 4. **API REST Adicional**
Además del protocolo MCP, endpoints REST disponibles:
- `/api/datos-tabla/:idTabla`
- `/api/datos-serie/:idSerie`
- `/api/operaciones-disponibles`
- `/api/operacion/:idOperacion`
- `/api/variables`
- `/api/variables-operacion/:idOperacion`
- `/api/series-operacion/:idOperacion`
- `/api/tablas-operacion/:idOperacion`
- `/health` - Health check
#### 5. **TypeScript Completo**
- ✅ Tipos para todas las funciones de la API INE
- ✅ Interfaces para parámetros y respuestas
- ✅ Código completamente tipado
- ✅ IntelliSense completo en VS Code
#### 6. **Configuración para AI Toolkit**
- ✅ Archivo `mcp-config.json` listo para usar
- ✅ Soporte para tres modos de transporte
- ✅ Documentación de configuración en README
#### 7. **Scripts de Instalación y Ejecución**
-`install.sh` - Instalación automatizada
-`start-server.sh` - Iniciar servidor HTTP
-`start-sse.sh` - Iniciar servidor SSE
- ✅ Scripts npm: `build`, `start`, `dev`, `start:sse`, `dev:sse`
#### 8. **Documentación Completa**
-`README.md` - Documentación principal detallada
-`QUICKSTART.md` - Guía rápida de inicio
- ✅ Ejemplos de consultas en diferentes formatos
- ✅ Troubleshooting y resolución de problemas
- ✅ Ejemplos de configuración para AI Toolkit
## 🚀 Estado Actual
### ✅ Completado y Probado
1. **Instalación**: ✅ Dependencias instaladas correctamente
2. **Compilación**: ✅ TypeScript compilado sin errores
3. **Servidor HTTP**: ✅ Funcionando en puerto 3000
4. **Health Check**: ✅ Responde correctamente
5. **Listado de herramientas**: ✅ 24 herramientas MCP disponibles
6. **Consulta real a API INE**: ✅ Obtiene datos correctamente
### 📊 Prueba Realizada
```bash
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"ine_operaciones_disponibles","arguments":{"idioma":"ES","det":1}},"id":2}'
```
**Resultado**: ✅ Devolvió 101 operaciones estadísticas del INE correctamente
## 📝 Próximos Pasos
### Para el Usuario:
1. **Configurar en AI Toolkit**:
- Abre VS Code
- Instala AI Toolkit (si no lo tienes)
- Configura el servidor MCP usando `mcp-config.json`
2. **Usar desde AI Toolkit**:
```
¿Cuál es el último valor del IPC en España?
Dame las operaciones estadísticas sobre población
Obtén los últimos 12 meses del IPC
```
3. **Documentación Swagger**:
- Visita http://localhost:3000/api-docs
- Explora y prueba los endpoints interactivamente
4. **Ejemplos de Código**:
- Ejecuta: `node dist/examples.js`
- Ve ejemplos de uso en TypeScript
## 🔧 Comandos Útiles
```bash
# Instalación
./install.sh
# Iniciar servidor HTTP (recomendado)
npm start
# o
./start-server.sh
# Iniciar servidor SSE
npm run start:sse
# o
./start-sse.sh
# Modo desarrollo (auto-recarga)
npm run dev
# Recompilar
npm run build
# Limpiar
npm run clean
npm run build
# Ver salud del servidor
curl http://localhost:3000/health
# Listar herramientas MCP
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'
```
## 🌐 URLs Importantes
- **Servidor MCP**: http://localhost:3000/mcp/v1
- **Documentación Swagger**: http://localhost:3000/api-docs
- **Health Check**: http://localhost:3000/health
- **Servidor SSE**: http://localhost:3001/sse
- **API INE Oficial**: https://servicios.ine.es/wstempus/js/
## 📚 Documentación de Referencia
- [API del INE](https://www.ine.es/dyngs/DataLab/manual.html?cid=45)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [VS Code AI Toolkit](https://marketplace.visualstudio.com/items?itemName=ms-windows-ai-studio.windows-ai-studio)
## 🎉 Resumen
El servidor MCP INE está **completamente funcional** y listo para usar con:
✅ 24 herramientas MCP para acceder a toda la API del INE
✅ Soporte completo para HTTP JSON-RPC, SSE y stdio
✅ Documentación Swagger interactiva
✅ Código TypeScript completamente tipado
✅ Scripts de instalación y ejecución
✅ Documentación completa y ejemplos de uso
✅ Configuración lista para VS Code AI Toolkit
✅ Probado y verificado funcionando correctamente
---
**Desarrollado con ❤️ para facilitar el acceso a los datos estadísticos del INE de España mediante el protocolo MCP.**

236
QUICKSTART.md Archivo normal
Ver fichero

@@ -0,0 +1,236 @@
# Guía Rápida de Configuración para VS Code AI Toolkit
## Configuración del Servidor MCP INE
### Paso 1: Iniciar el Servidor
Abre una terminal en la carpeta `mcp-ine` y ejecuta:
```bash
npm start
```
El servidor iniciará en `http://localhost:3000`
### Paso 2: Configurar AI Toolkit
1. Abre VS Code
2. Instala la extensión **AI Toolkit** (si no la tienes)
3. Presiona `Ctrl+Shift+P` (o `Cmd+Shift+P` en Mac)
4. Busca: **"AI Toolkit: Configure MCP Servers"**
5. Agrega la siguiente configuración:
```json
{
"mcpServers": {
"ine-spain": {
"url": "http://localhost:3000/mcp/v1",
"transport": "http",
"description": "API Estadísticas INE España"
}
}
}
```
### Paso 3: Verificar Conexión
En AI Toolkit, deberías ver el servidor "ine-spain" activo con las 24 herramientas disponibles.
## Ejemplos de Consultas en el Chat
Una vez configurado, puedes hacer preguntas directamente:
### Consultas sobre el IPC
```
¿Cuál es el último valor del IPC en España?
Dame los últimos 12 meses del IPC con formato amigable
¿Cuál ha sido la variación mensual del IPC en los últimos 6 meses?
```
### Consultas sobre Operaciones
```
¿Qué operaciones estadísticas tiene disponibles el INE?
Lista las operaciones relacionadas con población
Dame información sobre la operación IPC
```
### Consultas sobre Datos Específicos
```
Obtén los datos de la tabla 50902 de los últimos 3 períodos
¿Qué variables tiene la operación EPA (Encuesta de Población Activa)?
Dame las series de la operación IPC con periodicidad mensual
```
### Consultas con Filtros
```
Busca datos del IPC para Madrid con variación mensual
Dame los grupos ECOICOP del IPC
¿Qué provincias tiene disponibles la variable 115?
```
## Herramientas MCP Disponibles
### 🔢 Datos
- `ine_datos_tabla`: Datos de tablas
- `ine_datos_serie`: Datos de series temporales
- `ine_datos_metadata_operacion`: Datos con filtros avanzados
### 📊 Operaciones
- `ine_operaciones_disponibles`: Lista de operaciones
- `ine_operacion`: Info de operación específica
### 📈 Series
- `ine_serie`: Info de serie
- `ine_series_operacion`: Series de una operación
- `ine_series_tabla`: Series de una tabla
- `ine_valores_serie`: Variables de una serie
- `ine_serie_metadata_operacion`: Búsqueda avanzada
### 📋 Tablas
- `ine_tablas_operacion`: Tablas de una operación
- `ine_grupos_tabla`: Grupos de una tabla
- `ine_valores_grupos_tabla`: Valores de grupos
### 🏷️ Variables
- `ine_variables`: Lista de variables
- `ine_variables_operacion`: Variables de operación
- `ine_valores_variable`: Valores de variable
- `ine_valores_variable_operacion`: Valores en operación
- `ine_valores_hijos`: Valores jerárquicos
### 📚 Metadatos
- `ine_periodicidades`: Periodicidades disponibles
- `ine_publicaciones`: Lista de publicaciones
- `ine_publicaciones_operacion`: Publicaciones de operación
- `ine_publicacion_fecha_publicacion`: Fechas de publicación
- `ine_clasificaciones`: Clasificaciones
- `ine_clasificaciones_operacion`: Clasificaciones de operación
## Códigos de Operaciones Comunes
- **IPC**: Índice de Precios de Consumo
- **EPA**: Encuesta de Población Activa
- **CNE**: Contabilidad Nacional
- **30138**: IPC (código IOE)
- **30308**: EPA (código IOE)
## Códigos de Tablas Comunes
- **50902**: IPC - Índices nacionales: general y de grupos ECOICOP
- **50913**: IPC - Índices por comunidades autónomas
## Parámetros Útiles
### Idioma
- `ES`: Español (predeterminado)
- `EN`: Inglés
### Nivel de Detalle (`det`)
- `0`: Básico
- `1`: Medio
- `2`: Completo (recomendado para análisis detallado)
### Tipo de Respuesta (`tip`)
- `A`: Formato amigable/legible
- `M`: Con metadatos
- `AM`: Amigable con metadatos (recomendado)
### Periodicidad (`p`)
- `1`: Mensual
- `3`: Trimestral
- `6`: Semestral
- `12`: Anual
## Verificar Estado del Servidor
```bash
# Health check
curl http://localhost:3000/health
# Listar herramientas MCP
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'
```
## Documentación Swagger
Para explorar la API REST y probar endpoints:
🌐 **http://localhost:3000/api-docs**
## Troubleshooting
### No aparece el servidor en AI Toolkit
1. Verifica que el servidor esté corriendo: `http://localhost:3000/health`
2. Reinicia VS Code
3. Verifica la configuración MCP en AI Toolkit
### Errores de conexión
- Asegúrate de que no hay otro proceso en el puerto 3000
- Usa `netstat -tuln | grep 3000` para verificar
### El servidor no responde
- Verifica los logs de la terminal donde corre el servidor
- Reinicia el servidor con `npm start`
## Modos Alternativos
### Modo SSE (Server-Sent Events)
```bash
npm run start:sse
```
Configuración en AI Toolkit:
```json
{
"mcpServers": {
"ine-sse": {
"url": "http://localhost:3001/sse",
"transport": "sse"
}
}
}
```
### Modo stdio
```bash
node dist/index.js --stdio
```
Configuración en AI Toolkit:
```json
{
"mcpServers": {
"ine-stdio": {
"command": "node",
"args": ["dist/index.js", "--stdio"],
"cwd": "/ruta/completa/a/mcp-ine"
}
}
}
```
## Recursos Adicionales
- [Documentación API INE](https://www.ine.es/dyngs/DataLab/manual.html?cid=45)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [AI Toolkit Documentation](https://github.com/microsoft/vscode-ai-toolkit)
---
💡 **Tip**: Comienza preguntando por las operaciones disponibles para familiarizarte con los datos del INE.

372
README.md Archivo normal
Ver fichero

@@ -0,0 +1,372 @@
# MCP INE Server
Servidor MCP (Model Context Protocol) para consultar la API del Instituto Nacional de Estadística (INE) de España. Implementa soporte completo para JSON-RPC sobre HTTP y SSE (Server-Sent Events), optimizado para su uso con VS Code AI Toolkit.
## 🌟 Características
-**Protocolo MCP completo**: Soporte para JSON-RPC y SSE
-**24 herramientas MCP**: Acceso a todos los endpoints de la API del INE
-**Documentación Swagger**: API REST documentada con OpenAPI 3.0
-**TypeScript**: Código completamente tipado
-**VS Code AI Toolkit**: Configuración lista para usar
-**Múltiples transportes**: HTTP JSON-RPC, SSE y stdio
## 📋 Requisitos
- Node.js 18 o superior
- npm o yarn
## 🚀 Instalación
### Instalación rápida
```bash
chmod +x install.sh
./install.sh
```
### Instalación manual
```bash
# Instalar dependencias
npm install
# Compilar TypeScript
npm run build
```
## 🎮 Uso
### Modo HTTP JSON-RPC (Principal)
Este es el modo recomendado para AI Toolkit:
```bash
npm start
# o
./start-server.sh
```
El servidor estará disponible en:
- **Endpoint MCP**: `http://localhost:3000/mcp/v1`
- **Swagger UI**: `http://localhost:3000/api-docs`
- **Health Check**: `http://localhost:3000/health`
### Modo SSE (Server-Sent Events)
Para streaming de eventos:
```bash
npm run start:sse
# o
./start-sse.sh
```
El servidor SSE estará en:
- **Endpoint SSE**: `http://localhost:3001/sse`
- **Health Check**: `http://localhost:3001/health`
### Modo stdio
Para integración directa:
```bash
node dist/index.js --stdio
```
## 🔧 Configuración en VS Code AI Toolkit
### Opción 1: HTTP JSON-RPC (Recomendado)
1. Abre VS Code
2. Instala la extensión **AI Toolkit**
3. Inicia el servidor: `npm start`
4. En AI Toolkit, configura el servidor MCP:
```json
{
"mcpServers": {
"ine-server": {
"url": "http://localhost:3000/mcp/v1",
"transport": "http",
"description": "API del INE España"
}
}
}
```
### Opción 2: SSE
```json
{
"mcpServers": {
"ine-server-sse": {
"url": "http://localhost:3001/sse",
"transport": "sse",
"description": "API del INE España (SSE)"
}
}
}
```
### Opción 3: stdio
```json
{
"mcpServers": {
"ine-server-stdio": {
"command": "node",
"args": ["dist/index.js", "--stdio"],
"cwd": "/ruta/a/mcp-ine",
"description": "API del INE España (stdio)"
}
}
}
```
## 🛠️ Herramientas MCP Disponibles
El servidor proporciona 24 herramientas MCP para interactuar con la API del INE:
### Datos Estadísticos
- **`ine_datos_tabla`**: Obtiene datos de una tabla específica
- **`ine_datos_serie`**: Obtiene datos de una serie temporal
- **`ine_datos_metadata_operacion`**: Datos con filtros de metadata
### Operaciones
- **`ine_operaciones_disponibles`**: Lista todas las operaciones estadísticas
- **`ine_operacion`**: Información de una operación específica
### Variables y Valores
- **`ine_variables`**: Lista todas las variables disponibles
- **`ine_variables_operacion`**: Variables de una operación
- **`ine_valores_variable`**: Valores de una variable
- **`ine_valores_variable_operacion`**: Valores en contexto de operación
- **`ine_valores_hijos`**: Valores jerárquicos (ej: provincias de una CA)
### Series Temporales
- **`ine_serie`**: Información de una serie
- **`ine_series_operacion`**: Series de una operación
- **`ine_series_tabla`**: Series de una tabla
- **`ine_serie_metadata_operacion`**: Búsqueda con filtros
- **`ine_valores_serie`**: Variables que definen una serie
### Tablas
- **`ine_tablas_operacion`**: Tablas de una operación
- **`ine_grupos_tabla`**: Grupos de una tabla
- **`ine_valores_grupos_tabla`**: Valores de un grupo
### Metadatos
- **`ine_periodicidades`**: Periodicidades disponibles
- **`ine_publicaciones`**: Lista de publicaciones
- **`ine_publicaciones_operacion`**: Publicaciones de una operación
- **`ine_publicacion_fecha_publicacion`**: Fechas de publicación
- **`ine_clasificaciones`**: Clasificaciones disponibles
- **`ine_clasificaciones_operacion`**: Clasificaciones de una operación
## 📖 Ejemplos de Uso
### Ejemplo 1: Obtener datos del IPC
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "ine_datos_serie",
"arguments": {
"idSerie": "IPC251856",
"nult": 12,
"tip": "A"
}
},
"id": 1
}
```
### Ejemplo 2: Listar operaciones disponibles
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "ine_operaciones_disponibles",
"arguments": {
"idioma": "ES",
"geo": 0
}
},
"id": 2
}
```
### Ejemplo 3: Obtener variables del IPC
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "ine_variables_operacion",
"arguments": {
"idOperacion": "IPC"
}
},
"id": 3
}
```
### Desde AI Toolkit (Chat)
Una vez configurado en AI Toolkit, puedes hacer preguntas como:
```
¿Cuál es el último valor del IPC en España?
¿Qué operaciones estadísticas tiene el INE sobre población?
Dame los datos de la tabla 50902 de los últimos 5 períodos
¿Cuáles son las variables disponibles para la operación IPC?
```
## 🌐 API REST
Además del protocolo MCP, el servidor expone endpoints REST:
- `GET /api/datos-tabla/:idTabla` - Datos de tabla
- `GET /api/datos-serie/:idSerie` - Datos de serie
- `GET /api/operaciones-disponibles` - Listar operaciones
- `GET /api/operacion/:idOperacion` - Info de operación
- `GET /api/variables` - Listar variables
- `GET /api/variables-operacion/:idOperacion` - Variables de operación
- `GET /api/series-operacion/:idOperacion` - Series de operación
- `GET /api/tablas-operacion/:idOperacion` - Tablas de operación
Documentación completa en: `http://localhost:3000/api-docs`
## 📝 Parámetros Comunes
### Idioma
- `ES`: Español (por defecto)
- `EN`: Inglés
### Nivel de Detalle (det)
- `0`: Básico
- `1`: Medio
- `2`: Completo
### Tipo de Respuesta (tip)
- `A`: Amigable (legible)
- `M`: Con metadatos
- `AM`: Amigable con metadatos
### Periodicidad (p)
- `1`: Mensual
- `3`: Trimestral
- `6`: Semestral
- `12`: Anual
## 🔍 Ejemplos de Consultas desde curl
```bash
# Obtener últimos datos del IPC
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "ine_datos_serie",
"arguments": {"idSerie": "IPC251856", "nult": 1}
},
"id": 1
}'
# Listar herramientas disponibles
curl -X POST http://localhost:3000/mcp/v1 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": 1
}'
```
## 📚 Recursos
- [API del INE - Documentación oficial](https://www.ine.es/dyngs/DataLab/manual.html?cid=45)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [VS Code AI Toolkit](https://marketplace.visualstudio.com/items?itemName=ms-windows-ai-studio.windows-ai-studio)
## 🛡️ Estructura del Proyecto
```
mcp-ine/
├── src/
│ ├── index.ts # Servidor principal (HTTP JSON-RPC)
│ ├── server-sse.ts # Servidor SSE
│ ├── swagger.ts # Especificación OpenAPI
│ ├── types/
│ │ └── ine.types.ts # Tipos TypeScript
│ └── services/
│ └── ine-client.ts # Cliente HTTP para API INE
├── dist/ # Código compilado
├── package.json
├── tsconfig.json
├── mcp-config.json # Configuración para AI Toolkit
├── install.sh # Script de instalación
├── start-server.sh # Iniciar servidor HTTP
├── start-sse.sh # Iniciar servidor SSE
└── README.md
```
## 🐛 Troubleshooting
### El servidor no inicia
```bash
# Limpiar y reinstalar
npm run clean
rm -rf node_modules package-lock.json
npm install
npm run build
```
### Error de conexión en AI Toolkit
1. Verifica que el servidor esté corriendo: `http://localhost:3000/health`
2. Comprueba que no haya otro proceso usando el puerto 3000
3. Revisa la configuración MCP en AI Toolkit
### Errores de TypeScript
```bash
# Reinstalar tipos
npm install --save-dev @types/node @types/express
npm run build
```
## 📄 Licencia
MIT
## 🤝 Contribuciones
Las contribuciones son bienvenidas. Por favor, abre un issue o pull request.
## 📧 Soporte
Para reportar problemas o sugerencias, abre un issue en el repositorio.
---
Desarrollado con ❤️ para facilitar el acceso a los datos estadísticos del INE de España.

31
install.sh Archivo ejecutable
Ver fichero

@@ -0,0 +1,31 @@
#!/bin/bash
# Script de instalación y configuración
echo "📦 Instalando MCP INE Server..."
echo ""
# Instalar dependencias
echo "1⃣ Instalando dependencias de Node.js..."
npm install
# Compilar TypeScript
echo ""
echo "2⃣ Compilando TypeScript..."
npm run build
# Hacer scripts ejecutables
chmod +x start-server.sh
chmod +x start-sse.sh
echo ""
echo "✅ Instalación completada!"
echo ""
echo "Para iniciar el servidor, usa uno de estos comandos:"
echo " - Modo HTTP JSON-RPC: ./start-server.sh o npm start"
echo " - Modo SSE: ./start-sse.sh o npm run start:sse"
echo " - Modo stdio: node dist/index.js --stdio"
echo ""
echo "Documentación Swagger estará disponible en:"
echo " http://localhost:3000/api-docs"
echo ""

22
mcp-config.json Archivo normal
Ver fichero

@@ -0,0 +1,22 @@
{
"mcpServers": {
"ine-server": {
"command": "node",
"args": ["dist/index.js", "--stdio"],
"description": "Servidor MCP para consultar la API del INE (Instituto Nacional de Estadística de España)",
"env": {}
},
"ine-server-http": {
"url": "http://localhost:3000/mcp/v1",
"transport": "http",
"description": "Servidor MCP INE vía HTTP JSON-RPC",
"env": {}
},
"ine-server-sse": {
"url": "http://localhost:3001/sse",
"transport": "sse",
"description": "Servidor MCP INE vía SSE (Server-Sent Events)",
"env": {}
}
}
}

2289
package-lock.json generado Archivo normal

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

42
package.json Archivo normal
Ver fichero

@@ -0,0 +1,42 @@
{
"name": "mcp-ine-server",
"version": "1.0.0",
"description": "MCP Server para la API del INE (Instituto Nacional de Estadística)",
"main": "dist/index.js",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"start:sse": "node dist/server-sse.js",
"dev": "tsx watch src/index.ts",
"dev:sse": "tsx watch src/server-sse.ts",
"clean": "rm -rf dist",
"prepare": "npm run build"
},
"keywords": [
"mcp",
"ine",
"estadistica",
"spain",
"api",
"model-context-protocol"
],
"author": "",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
"express": "^4.18.2",
"axios": "^1.6.5",
"swagger-ui-express": "^5.0.0",
"cors": "^2.8.5",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^20.11.5",
"@types/swagger-ui-express": "^4.1.6",
"@types/cors": "^2.8.17",
"typescript": "^5.3.3",
"tsx": "^4.7.0"
}
}

248
src/examples.ts Archivo normal
Ver fichero

@@ -0,0 +1,248 @@
/**
* Ejemplos de uso del MCP INE Server
* Ejecutar con: node dist/examples.js
*/
import axios from 'axios';
const MCP_ENDPOINT = 'http://localhost:3000/mcp/v1';
/**
* Función helper para llamar al servidor MCP
*/
async function callMCPTool(toolName: string, args: any = {}) {
try {
const response = await axios.post(MCP_ENDPOINT, {
jsonrpc: '2.0',
method: 'tools/call',
params: {
name: toolName,
arguments: args
},
id: Date.now()
});
return response.data;
} catch (error: any) {
console.error(`Error llamando a ${toolName}:`, error.message);
return null;
}
}
/**
* Ejemplo 1: Obtener últimos datos del IPC
*/
async function ejemplo1_datosIPC() {
console.log('\n📊 Ejemplo 1: Últimos datos del IPC\n');
const result = await callMCPTool('ine_datos_serie', {
idSerie: 'IPC251856',
nult: 12,
tip: 'A',
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
console.log(JSON.parse(result.result.content[0].text));
}
}
/**
* Ejemplo 2: Listar operaciones disponibles
*/
async function ejemplo2_operaciones() {
console.log('\n📋 Ejemplo 2: Operaciones Disponibles\n');
const result = await callMCPTool('ine_operaciones_disponibles', {
idioma: 'ES',
geo: 0,
det: 1
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log(`Total de operaciones: ${data.data?.length || 0}`);
console.log('Primeras 5 operaciones:');
data.data?.slice(0, 5).forEach((op: any) => {
console.log(`- ${op.Nombre} (${op.Id})`);
});
}
}
/**
* Ejemplo 3: Obtener variables de la operación IPC
*/
async function ejemplo3_variablesIPC() {
console.log('\n🏷 Ejemplo 3: Variables de la Operación IPC\n');
const result = await callMCPTool('ine_variables_operacion', {
idOperacion: 'IPC',
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log('Variables del IPC:');
data.data?.slice(0, 10).forEach((variable: any) => {
console.log(`- ${variable.Nombre} (ID: ${variable.Id})`);
});
}
}
/**
* Ejemplo 4: Obtener datos de una tabla
*/
async function ejemplo4_datosTabla() {
console.log('\n📈 Ejemplo 4: Datos de Tabla 50902\n');
const result = await callMCPTool('ine_datos_tabla', {
idTabla: '50902',
nult: 3,
tip: 'A',
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log('Últimos 3 períodos de la tabla 50902:');
console.log(JSON.stringify(data, null, 2));
}
}
/**
* Ejemplo 5: Obtener información de una operación
*/
async function ejemplo5_infoOperacion() {
console.log('\n📖 Ejemplo 5: Información de la Operación IPC\n');
const result = await callMCPTool('ine_operacion', {
idOperacion: 'IPC',
det: 2,
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log('Información del IPC:');
console.log(JSON.stringify(data, null, 2));
}
}
/**
* Ejemplo 6: Buscar series con filtros
*/
async function ejemplo6_seriesConFiltros() {
console.log('\n🔍 Ejemplo 6: Series del IPC con Filtros\n');
const result = await callMCPTool('ine_datos_metadata_operacion', {
idOperacion: 'IPC',
p: 1, // Periodicidad mensual
nult: 1,
g1: '115:29', // Madrid
g2: '3:84', // Variación mensual
tip: 'A',
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log('Datos del IPC para Madrid:');
console.log(JSON.stringify(data, null, 2));
}
}
/**
* Ejemplo 7: Listar herramientas disponibles
*/
async function ejemplo7_listarHerramientas() {
console.log('\n🛠 Ejemplo 7: Herramientas MCP Disponibles\n');
try {
const response = await axios.post(MCP_ENDPOINT, {
jsonrpc: '2.0',
method: 'tools/list',
params: {},
id: 1
});
const tools = response.data.result.tools;
console.log(`Total de herramientas: ${tools.length}\n`);
tools.forEach((tool: any) => {
console.log(`- ${tool.name}`);
console.log(` ${tool.description}`);
console.log('');
});
} catch (error: any) {
console.error('Error listando herramientas:', error.message);
}
}
/**
* Ejemplo 8: Obtener periodicidades
*/
async function ejemplo8_periodicidades() {
console.log('\n⏰ Ejemplo 8: Periodicidades Disponibles\n');
const result = await callMCPTool('ine_periodicidades', {
idioma: 'ES'
});
if (result?.result?.content?.[0]?.text) {
const data = JSON.parse(result.result.content[0].text);
console.log('Periodicidades:');
data.data?.forEach((per: any) => {
console.log(`- ${per.Nombre} (ID: ${per.Id})`);
});
}
}
/**
* Ejecutar todos los ejemplos
*/
async function ejecutarTodos() {
console.log('='.repeat(60));
console.log(' EJEMPLOS DE USO DEL MCP INE SERVER');
console.log('='.repeat(60));
console.log('\n⚠ Asegúrate de que el servidor esté corriendo en el puerto 3000');
console.log(' Comando: npm start\n');
// Verificar que el servidor esté activo
try {
await axios.get('http://localhost:3000/health');
console.log('✅ Servidor MCP INE activo\n');
} catch (error) {
console.error('❌ Error: El servidor no está activo. Inicia el servidor con: npm start');
process.exit(1);
}
await ejemplo7_listarHerramientas();
await ejemplo1_datosIPC();
await ejemplo2_operaciones();
await ejemplo3_variablesIPC();
await ejemplo4_datosTabla();
await ejemplo5_infoOperacion();
await ejemplo8_periodicidades();
await ejemplo6_seriesConFiltros();
console.log('\n' + '='.repeat(60));
console.log(' FIN DE LOS EJEMPLOS');
console.log('='.repeat(60));
}
// Ejecutar si se llama directamente
if (import.meta.url === `file://${process.argv[1]}`) {
ejecutarTodos().catch(console.error);
}
export {
callMCPTool,
ejemplo1_datosIPC,
ejemplo2_operaciones,
ejemplo3_variablesIPC,
ejemplo4_datosTabla,
ejemplo5_infoOperacion,
ejemplo6_seriesConFiltros,
ejemplo7_listarHerramientas,
ejemplo8_periodicidades
};

611
src/index.ts Archivo normal
Ver fichero

@@ -0,0 +1,611 @@
import express, { Request, Response } from 'express';
import cors from 'cors';
import swaggerUi from 'swagger-ui-express';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
Tool
} from '@modelcontextprotocol/sdk/types.js';
import { ineClient } from './services/ine-client.js';
import { swaggerSpec } from './swagger.js';
import type { Idioma } from './types/ine.types.js';
const PORT = process.env.PORT || 3000;
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
// Swagger Documentation
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// Health check
app.get('/health', (req: Request, res: Response) => {
res.json({
status: 'ok',
timestamp: new Date().toISOString(),
service: 'MCP INE Server'
});
});
/**
* Definición de herramientas MCP para la API del INE
*/
const tools: Tool[] = [
{
name: 'ine_datos_tabla',
description: 'Obtiene datos de una tabla específica del INE. Permite filtrar por periodos, nivel de detalle y variables.',
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID de la tabla (ej: 50902)' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
nult: { type: 'number', description: 'Número de últimos periodos' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Tipo: A=amigable, M=metadatos, AM=ambos' },
tv: { type: 'string', description: 'Filtro de variables (formato: id_variable:id_valor)' },
date: { type: 'string', description: 'Rango de fechas (formato: aaaammdd:aaaammdd)' }
},
required: ['idTabla']
}
},
{
name: 'ine_datos_serie',
description: 'Obtiene datos de una serie temporal específica del INE.',
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string', description: 'Código de la serie (ej: IPC251856)' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
nult: { type: 'number', description: 'Número de últimos periodos' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Tipo de respuesta' },
date: { type: 'string', description: 'Rango de fechas' }
},
required: ['idSerie']
}
},
{
name: 'ine_datos_metadata_operacion',
description: 'Obtiene datos de series usando filtros de metadata de una operación.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de operación (ej: IPC)' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
p: { type: 'number', description: 'Periodicidad (1=mensual, 3=trimestral, 12=anual)' },
nult: { type: 'number', description: 'Número de últimos periodos' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] },
g1: { type: 'string', description: 'Filtro 1 (formato: id_variable:id_valor)' },
g2: { type: 'string', description: 'Filtro 2' },
g3: { type: 'string', description: 'Filtro 3' },
g4: { type: 'string', description: 'Filtro 4' },
g5: { type: 'string', description: 'Filtro 5' }
},
required: ['idOperacion']
}
},
{
name: 'ine_operaciones_disponibles',
description: 'Lista todas las operaciones estadísticas disponibles en el INE.',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
geo: { type: 'number', enum: [0, 1], description: '0=nacional, 1=geográfico' },
page: { type: 'number', description: 'Página (500 elementos por página)' }
}
}
},
{
name: 'ine_operacion',
description: 'Obtiene información detallada de una operación estadística.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de operación' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idOperacion']
}
},
{
name: 'ine_variables',
description: 'Lista todas las variables estadísticas disponibles.',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
page: { type: 'number' }
}
}
},
{
name: 'ine_variables_operacion',
description: 'Obtiene las variables utilizadas en una operación específica.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
page: { type: 'number' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_variable',
description: 'Obtiene todos los valores posibles de una variable.',
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string', description: 'ID de la variable' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
clasif: { type: 'number', description: 'ID de clasificación' }
},
required: ['idVariable']
}
},
{
name: 'ine_valores_variable_operacion',
description: 'Obtiene valores de una variable en el contexto de una operación.',
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string' },
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idVariable', 'idOperacion']
}
},
{
name: 'ine_tablas_operacion',
description: 'Lista todas las tablas de una operación estadística.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
geo: { type: 'number', enum: [0, 1] },
tip: { type: 'string', enum: ['A'] }
},
required: ['idOperacion']
}
},
{
name: 'ine_grupos_tabla',
description: 'Obtiene los grupos de selección que definen una tabla.',
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
required: ['idTabla']
}
},
{
name: 'ine_valores_grupos_tabla',
description: 'Obtiene los valores de un grupo específico de una tabla.',
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string' },
idGrupo: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idTabla', 'idGrupo']
}
},
{
name: 'ine_serie',
description: 'Obtiene información completa de una serie temporal.',
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] }
},
required: ['idSerie']
}
},
{
name: 'ine_series_operacion',
description: 'Lista todas las series de una operación.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] },
page: { type: 'number' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_serie',
description: 'Obtiene las variables y valores que definen una serie.',
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idSerie']
}
},
{
name: 'ine_series_tabla',
description: 'Obtiene todas las series de una tabla específica.',
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] },
tv: { type: 'string', description: 'Filtro de variables' }
},
required: ['idTabla']
}
},
{
name: 'ine_serie_metadata_operacion',
description: 'Busca series usando filtros de metadata en una operación.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
p: { type: 'number', description: 'Periodicidad' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] },
g1: { type: 'string' },
g2: { type: 'string' },
g3: { type: 'string' },
g4: { type: 'string' },
g5: { type: 'string' }
},
required: ['idOperacion']
}
},
{
name: 'ine_periodicidades',
description: 'Lista todas las periodicidades disponibles (mensual, trimestral, etc.).',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
}
}
},
{
name: 'ine_publicaciones',
description: 'Lista todas las publicaciones estadísticas disponibles.',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A'] }
}
}
},
{
name: 'ine_publicaciones_operacion',
description: 'Obtiene las publicaciones de una operación específica.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A'] }
},
required: ['idOperacion']
}
},
{
name: 'ine_publicacion_fecha_publicacion',
description: 'Obtiene las fechas de publicación para una publicación dada.',
inputSchema: {
type: 'object',
properties: {
idPublicacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A'] }
},
required: ['idPublicacion']
}
},
{
name: 'ine_clasificaciones',
description: 'Lista todas las clasificaciones estadísticas disponibles.',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
}
}
},
{
name: 'ine_clasificaciones_operacion',
description: 'Obtiene las clasificaciones utilizadas en una operación.',
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_hijos',
description: 'Obtiene valores hijos en una estructura jerárquica (ej: provincias de una comunidad).',
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string', description: 'ID de la variable' },
idValor: { type: 'string', description: 'ID del valor padre' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idVariable', 'idValor']
}
}
];
/**
* Maneja las llamadas a las herramientas MCP
*/
async function handleToolCall(name: string, args: any): Promise<any> {
const idioma = (args.idioma || 'ES') as Idioma;
switch (name) {
case 'ine_datos_tabla':
return await ineClient.getDatosTabla(args.idTabla, args, idioma);
case 'ine_datos_serie':
return await ineClient.getDatosSerie(args.idSerie, args, idioma);
case 'ine_datos_metadata_operacion':
return await ineClient.getDatosMetadataOperacion(args.idOperacion, args, idioma);
case 'ine_operaciones_disponibles':
return await ineClient.getOperacionesDisponibles(args, idioma);
case 'ine_operacion':
return await ineClient.getOperacion(args.idOperacion, args, idioma);
case 'ine_variables':
return await ineClient.getVariables(args, idioma);
case 'ine_variables_operacion':
return await ineClient.getVariablesOperacion(args.idOperacion, args, idioma);
case 'ine_valores_variable':
return await ineClient.getValoresVariable(args.idVariable, args, idioma);
case 'ine_valores_variable_operacion':
return await ineClient.getValoresVariableOperacion(args.idVariable, args.idOperacion, args, idioma);
case 'ine_tablas_operacion':
return await ineClient.getTablasOperacion(args.idOperacion, args, idioma);
case 'ine_grupos_tabla':
return await ineClient.getGruposTabla(args.idTabla, idioma);
case 'ine_valores_grupos_tabla':
return await ineClient.getValoresGruposTabla(args.idTabla, args.idGrupo, args, idioma);
case 'ine_serie':
return await ineClient.getSerie(args.idSerie, args, idioma);
case 'ine_series_operacion':
return await ineClient.getSeriesOperacion(args.idOperacion, args, idioma);
case 'ine_valores_serie':
return await ineClient.getValoresSerie(args.idSerie, args, idioma);
case 'ine_series_tabla':
return await ineClient.getSeriesTabla(args.idTabla, args, idioma);
case 'ine_serie_metadata_operacion':
return await ineClient.getSerieMetadataOperacion(args.idOperacion, args, idioma);
case 'ine_periodicidades':
return await ineClient.getPeriodicidades(idioma);
case 'ine_publicaciones':
return await ineClient.getPublicaciones(args, idioma);
case 'ine_publicaciones_operacion':
return await ineClient.getPublicacionesOperacion(args.idOperacion, args, idioma);
case 'ine_publicacion_fecha_publicacion':
return await ineClient.getPublicacionFechaPublicacion(args.idPublicacion, args, idioma);
case 'ine_clasificaciones':
return await ineClient.getClasificaciones(idioma);
case 'ine_clasificaciones_operacion':
return await ineClient.getClasificacionesOperacion(args.idOperacion, idioma);
case 'ine_valores_hijos':
return await ineClient.getValoresHijos(args.idVariable, args.idValor, args, idioma);
default:
throw new Error(`Herramienta desconocida: ${name}`);
}
}
/**
* Endpoint JSON-RPC para MCP
*/
app.post('/mcp/v1', async (req: Request, res: Response) => {
try {
const { jsonrpc, method, params, id } = req.body;
if (jsonrpc !== '2.0') {
return res.status(400).json({
jsonrpc: '2.0',
error: { code: -32600, message: 'Invalid Request' },
id: null
});
}
// Listar herramientas
if (method === 'tools/list') {
return res.json({
jsonrpc: '2.0',
result: { tools },
id
});
}
// Llamar a una herramienta
if (method === 'tools/call') {
const { name, arguments: args } = params;
const result = await handleToolCall(name, args || {});
return res.json({
jsonrpc: '2.0',
result: {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
},
id
});
}
// Método no soportado
return res.status(404).json({
jsonrpc: '2.0',
error: { code: -32601, message: 'Method not found' },
id
});
} catch (error: any) {
console.error('Error en MCP:', error);
return res.status(500).json({
jsonrpc: '2.0',
error: { code: -32603, message: error.message || 'Internal error' },
id: req.body.id || null
});
}
});
// API REST endpoints (adicionales para compatibilidad)
app.get('/api/datos-tabla/:idTabla', async (req, res) => {
const result = await ineClient.getDatosTabla(req.params.idTabla, req.query as any);
res.json(result);
});
app.get('/api/datos-serie/:idSerie', async (req, res) => {
const result = await ineClient.getDatosSerie(req.params.idSerie, req.query as any);
res.json(result);
});
app.get('/api/operaciones-disponibles', async (req, res) => {
const result = await ineClient.getOperacionesDisponibles(req.query as any);
res.json(result);
});
app.get('/api/operacion/:idOperacion', async (req, res) => {
const result = await ineClient.getOperacion(req.params.idOperacion, req.query as any);
res.json(result);
});
app.get('/api/variables', async (req, res) => {
const result = await ineClient.getVariables(req.query as any);
res.json(result);
});
app.get('/api/variables-operacion/:idOperacion', async (req, res) => {
const result = await ineClient.getVariablesOperacion(req.params.idOperacion, req.query as any);
res.json(result);
});
app.get('/api/series-operacion/:idOperacion', async (req, res) => {
const result = await ineClient.getSeriesOperacion(req.params.idOperacion, req.query as any);
res.json(result);
});
app.get('/api/tablas-operacion/:idOperacion', async (req, res) => {
const result = await ineClient.getTablasOperacion(req.params.idOperacion, req.query as any);
res.json(result);
});
// Iniciar servidor HTTP
app.listen(PORT, () => {
console.log(`🚀 MCP INE Server ejecutándose en http://localhost:${PORT}`);
console.log(`📚 Documentación Swagger: http://localhost:${PORT}/api-docs`);
console.log(`🔧 Endpoint MCP JSON-RPC: http://localhost:${PORT}/mcp/v1`);
console.log(`💚 Health check: http://localhost:${PORT}/health`);
});
// Para uso con stdio (AI Toolkit)
export async function runStdioServer() {
const server = new Server(
{
name: 'ine-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Registrar handlers
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const result = await handleToolCall(name, args || {});
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
});
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('MCP INE Server iniciado en modo stdio');
}
// Si se ejecuta directamente con --stdio
if (process.argv.includes('--stdio')) {
runStdioServer().catch(console.error);
}

215
src/server-sse.ts Archivo normal
Ver fichero

@@ -0,0 +1,215 @@
import express, { Request, Response } from 'express';
import cors from 'cors';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
import { ineClient } from './services/ine-client.js';
import type { Idioma } from './types/ine.types.js';
const PORT = process.env.PORT || 3001;
const app = express();
app.use(cors());
app.use(express.json());
// Almacenamiento de sesiones SSE
const sessions = new Map<string, { server: Server; transport: SSEServerTransport }>();
/**
* Maneja las llamadas a las herramientas MCP
*/
async function handleToolCall(name: string, args: any): Promise<any> {
const idioma = (args.idioma || 'ES') as Idioma;
switch (name) {
case 'ine_datos_tabla':
return await ineClient.getDatosTabla(args.idTabla, args, idioma);
case 'ine_datos_serie':
return await ineClient.getDatosSerie(args.idSerie, args, idioma);
case 'ine_datos_metadata_operacion':
return await ineClient.getDatosMetadataOperacion(args.idOperacion, args, idioma);
case 'ine_operaciones_disponibles':
return await ineClient.getOperacionesDisponibles(args, idioma);
case 'ine_operacion':
return await ineClient.getOperacion(args.idOperacion, args, idioma);
case 'ine_variables':
return await ineClient.getVariables(args, idioma);
case 'ine_variables_operacion':
return await ineClient.getVariablesOperacion(args.idOperacion, args, idioma);
case 'ine_valores_variable':
return await ineClient.getValoresVariable(args.idVariable, args, idioma);
case 'ine_valores_variable_operacion':
return await ineClient.getValoresVariableOperacion(args.idVariable, args.idOperacion, args, idioma);
case 'ine_tablas_operacion':
return await ineClient.getTablasOperacion(args.idOperacion, args, idioma);
case 'ine_grupos_tabla':
return await ineClient.getGruposTabla(args.idTabla, idioma);
case 'ine_valores_grupos_tabla':
return await ineClient.getValoresGruposTabla(args.idTabla, args.idGrupo, args, idioma);
case 'ine_serie':
return await ineClient.getSerie(args.idSerie, args, idioma);
case 'ine_series_operacion':
return await ineClient.getSeriesOperacion(args.idOperacion, args, idioma);
case 'ine_valores_serie':
return await ineClient.getValoresSerie(args.idSerie, args, idioma);
case 'ine_series_tabla':
return await ineClient.getSeriesTabla(args.idTabla, args, idioma);
case 'ine_serie_metadata_operacion':
return await ineClient.getSerieMetadataOperacion(args.idOperacion, args, idioma);
case 'ine_periodicidades':
return await ineClient.getPeriodicidades(idioma);
case 'ine_publicaciones':
return await ineClient.getPublicaciones(args, idioma);
case 'ine_publicaciones_operacion':
return await ineClient.getPublicacionesOperacion(args.idOperacion, args, idioma);
case 'ine_publicacion_fecha_publicacion':
return await ineClient.getPublicacionFechaPublicacion(args.idPublicacion, args, idioma);
case 'ine_clasificaciones':
return await ineClient.getClasificaciones(idioma);
case 'ine_clasificaciones_operacion':
return await ineClient.getClasificacionesOperacion(args.idOperacion, idioma);
case 'ine_valores_hijos':
return await ineClient.getValoresHijos(args.idVariable, args.idValor, args, idioma);
default:
throw new Error(`Herramienta desconocida: ${name}`);
}
}
// Definición de herramientas (mismo que en index.ts)
const tools = [
{
name: 'ine_datos_tabla',
description: 'Obtiene datos de una tabla específica del INE',
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID de la tabla' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
nult: { type: 'number' },
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] }
},
required: ['idTabla']
}
},
{
name: 'ine_datos_serie',
description: 'Obtiene datos de una serie temporal',
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
nult: { type: 'number' },
det: { type: 'number', enum: [0, 1, 2] }
},
required: ['idSerie']
}
},
{
name: 'ine_operaciones_disponibles',
description: 'Lista todas las operaciones estadísticas',
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
geo: { type: 'number', enum: [0, 1] },
page: { type: 'number' }
}
}
}
// Agregar el resto de herramientas según sea necesario
];
/**
* Endpoint SSE para conexión MCP
*/
app.get('/sse', async (req: Request, res: Response) => {
const sessionId = Math.random().toString(36).substring(7);
// Configurar SSE
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// Crear servidor MCP
const server = new Server(
{
name: 'ine-mcp-server-sse',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Registrar handlers
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const result = await handleToolCall(name, args || {});
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
});
// Crear transporte SSE
const transport = new SSEServerTransport('/messages', res);
await server.connect(transport);
sessions.set(sessionId, { server, transport });
// Limpiar al cerrar conexión
req.on('close', () => {
sessions.delete(sessionId);
console.log(`Sesión SSE cerrada: ${sessionId}`);
});
console.log(`Nueva sesión SSE iniciada: ${sessionId}`);
});
/**
* Endpoint para enviar mensajes (POST)
*/
app.post('/messages', async (req: Request, res: Response) => {
try {
// Este endpoint procesa mensajes enviados por el cliente
const message = req.body;
console.log('Mensaje recibido:', message);
res.json({ success: true });
} catch (error: any) {
console.error('Error procesando mensaje:', error);
res.status(500).json({ error: error.message });
}
});
// Health check
app.get('/health', (req: Request, res: Response) => {
res.json({
status: 'ok',
transport: 'SSE',
sessions: sessions.size,
timestamp: new Date().toISOString()
});
});
app.listen(PORT, () => {
console.log(`🚀 MCP INE Server (SSE) ejecutándose en http://localhost:${PORT}`);
console.log(`📡 Endpoint SSE: http://localhost:${PORT}/sse`);
console.log(`💚 Health check: http://localhost:${PORT}/health`);
});

283
src/services/ine-client.ts Archivo normal
Ver fichero

@@ -0,0 +1,283 @@
import axios, { AxiosInstance } from 'axios';
import type {
Idioma,
DatosTablaParams,
DatosSerieParams,
DatosMetadataOperacionParams,
OperacionesDisponiblesParams,
OperacionParams,
VariablesParams,
VariablesOperacionParams,
ValoresVariableParams,
ValoresVariableOperacionParams,
TablasOperacionParams,
ValoresGruposTablaParams,
SerieParams,
SeriesOperacionParams,
ValoresSerieParams,
SeriesTablaParams,
SerieMetadataOperacionParams,
PublicacionesParams,
PublicacionesOperacionParams,
PublicacionFechaPublicacionParams,
ValoresHijosParams,
INEResponse
} from '../types/ine.types.js';
/**
* Cliente para la API del INE
*/
export class INEClient {
private readonly baseURL = 'https://servicios.ine.es/wstempus/js';
private readonly client: AxiosInstance;
constructor() {
this.client = axios.create({
baseURL: this.baseURL,
timeout: 30000,
headers: {
'Accept': 'application/json',
'User-Agent': 'MCP-INE-Server/1.0'
}
});
}
/**
* Construye la URL con parámetros
*/
private buildURL(idioma: Idioma, funcion: string, input?: string, params?: Record<string, any>): string {
let url = `/${idioma}/${funcion}`;
if (input) {
url += `/${input}`;
}
if (params && Object.keys(params).length > 0) {
const queryParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
queryParams.append(key, String(value));
}
});
const queryString = queryParams.toString();
if (queryString) {
url += `?${queryString}`;
}
}
return url;
}
/**
* Realiza una petición GET a la API
*/
private async get<T>(url: string): Promise<INEResponse<T>> {
try {
const response = await this.client.get<T>(url);
return {
data: response.data,
success: true
};
} catch (error: any) {
return {
data: null as any,
success: false,
error: error.message || 'Error desconocido'
};
}
}
/**
* DATOS_TABLA - Obtener datos para una tabla específica
*/
async getDatosTabla(idTabla: string, params?: DatosTablaParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'DATOS_TABLA', idTabla, params);
return this.get(url);
}
/**
* DATOS_SERIE - Obtener datos para una serie específica
*/
async getDatosSerie(idSerie: string, params?: DatosSerieParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'DATOS_SERIE', idSerie, params);
return this.get(url);
}
/**
* DATOS_METADATAOPERACION - Obtener datos de series usando filtros
*/
async getDatosMetadataOperacion(idOperacion: string, params?: DatosMetadataOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'DATOS_METADATAOPERACION', idOperacion, params);
return this.get(url);
}
/**
* OPERACIONES_DISPONIBLES - Obtener todas las operaciones disponibles
*/
async getOperacionesDisponibles(params?: OperacionesDisponiblesParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'OPERACIONES_DISPONIBLES', undefined, params);
return this.get(url);
}
/**
* OPERACION - Obtener una operación específica
*/
async getOperacion(idOperacion: string, params?: OperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'OPERACION', idOperacion, params);
return this.get(url);
}
/**
* VARIABLES - Obtener todas las variables disponibles
*/
async getVariables(params?: VariablesParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VARIABLES', undefined, params);
return this.get(url);
}
/**
* VARIABLES_OPERACION - Obtener variables de una operación
*/
async getVariablesOperacion(idOperacion: string, params?: VariablesOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VARIABLES_OPERACION', idOperacion, params);
return this.get(url);
}
/**
* VALORES_VARIABLE - Obtener valores de una variable
*/
async getValoresVariable(idVariable: string, params?: ValoresVariableParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VALORES_VARIABLE', idVariable, params);
return this.get(url);
}
/**
* VALORES_VARIABLEOPERACION - Obtener valores de una variable en una operación
*/
async getValoresVariableOperacion(idVariable: string, idOperacion: string, params?: ValoresVariableOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VALORES_VARIABLEOPERACION', `${idVariable}/${idOperacion}`, params);
return this.get(url);
}
/**
* TABLAS_OPERACION - Obtener tablas de una operación
*/
async getTablasOperacion(idOperacion: string, params?: TablasOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'TABLAS_OPERACION', idOperacion, params);
return this.get(url);
}
/**
* GRUPOS_TABLA - Obtener grupos de una tabla
*/
async getGruposTabla(idTabla: string, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'GRUPOS_TABLA', idTabla);
return this.get(url);
}
/**
* VALORES_GRUPOSTABLA - Obtener valores de un grupo de tabla
*/
async getValoresGruposTabla(idTabla: string, idGrupo: string, params?: ValoresGruposTablaParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VALORES_GRUPOSTABLA', `${idTabla}/${idGrupo}`, params);
return this.get(url);
}
/**
* SERIE - Obtener información de una serie
*/
async getSerie(idSerie: string, params?: SerieParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'SERIE', idSerie, params);
return this.get(url);
}
/**
* SERIES_OPERACION - Obtener series de una operación
*/
async getSeriesOperacion(idOperacion: string, params?: SeriesOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'SERIES_OPERACION', idOperacion, params);
return this.get(url);
}
/**
* VALORES_SERIE - Obtener valores y variables que definen una serie
*/
async getValoresSerie(idSerie: string, params?: ValoresSerieParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VALORES_SERIE', idSerie, params);
return this.get(url);
}
/**
* SERIES_TABLA - Obtener series de una tabla
*/
async getSeriesTabla(idTabla: string, params?: SeriesTablaParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'SERIES_TABLA', idTabla, params);
return this.get(url);
}
/**
* SERIE_METADATAOPERACION - Obtener series con filtros de metadata
*/
async getSerieMetadataOperacion(idOperacion: string, params?: SerieMetadataOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'SERIE_METADATAOPERACION', idOperacion, params);
return this.get(url);
}
/**
* PERIODICIDADES - Obtener periodicidades disponibles
*/
async getPeriodicidades(idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'PERIODICIDADES');
return this.get(url);
}
/**
* PUBLICACIONES - Obtener publicaciones disponibles
*/
async getPublicaciones(params?: PublicacionesParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'PUBLICACIONES', undefined, params);
return this.get(url);
}
/**
* PUBLICACIONES_OPERACION - Obtener publicaciones de una operación
*/
async getPublicacionesOperacion(idOperacion: string, params?: PublicacionesOperacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'PUBLICACIONES_OPERACION', idOperacion, params);
return this.get(url);
}
/**
* PUBLICACIONFECHA_PUBLICACION - Obtener fechas de publicación
*/
async getPublicacionFechaPublicacion(idPublicacion: string, params?: PublicacionFechaPublicacionParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'PUBLICACIONFECHA_PUBLICACION', idPublicacion, params);
return this.get(url);
}
/**
* CLASIFICACIONES - Obtener clasificaciones disponibles
*/
async getClasificaciones(idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'CLASIFICACIONES');
return this.get(url);
}
/**
* CLASIFICACIONES_OPERACION - Obtener clasificaciones de una operación
*/
async getClasificacionesOperacion(idOperacion: string, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'CLASIFICACIONES_OPERACION', idOperacion);
return this.get(url);
}
/**
* VALORES_HIJOS - Obtener valores hijos en estructura jerárquica
*/
async getValoresHijos(idVariable: string, idValor: string, params?: ValoresHijosParams, idioma: Idioma = 'ES') {
const url = this.buildURL(idioma, 'VALORES_HIJOS', `${idVariable}/${idValor}`, params);
return this.get(url);
}
}
// Exportar instancia singleton
export const ineClient = new INEClient();

346
src/swagger.ts Archivo normal
Ver fichero

@@ -0,0 +1,346 @@
/**
* Especificación OpenAPI para la API del INE MCP Server
*/
export const swaggerSpec = {
openapi: '3.0.0',
info: {
title: 'INE MCP Server API',
version: '1.0.0',
description: 'Servidor MCP para consultar la API del Instituto Nacional de Estadística (INE) de España',
contact: {
name: 'API Support',
url: 'https://github.com/your-repo/mcp-ine-server'
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT'
}
},
servers: [
{
url: 'http://localhost:3000',
description: 'Servidor de desarrollo'
}
],
tags: [
{ name: 'MCP', description: 'Endpoints del protocolo MCP' },
{ name: 'Datos', description: 'Consulta de datos estadísticos' },
{ name: 'Operaciones', description: 'Gestión de operaciones estadísticas' },
{ name: 'Variables', description: 'Gestión de variables' },
{ name: 'Series', description: 'Gestión de series temporales' },
{ name: 'Tablas', description: 'Gestión de tablas estadísticas' },
{ name: 'Metadatos', description: 'Información de metadatos' }
],
paths: {
'/mcp/v1': {
post: {
tags: ['MCP'],
summary: 'Endpoint JSON-RPC del protocolo MCP',
description: 'Endpoint principal para comunicación JSON-RPC con el servidor MCP',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
jsonrpc: { type: 'string', example: '2.0' },
method: { type: 'string', example: 'tools/call' },
params: { type: 'object' },
id: { type: 'number' }
}
}
}
}
},
responses: {
'200': {
description: 'Respuesta exitosa',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
jsonrpc: { type: 'string' },
result: { type: 'object' },
id: { type: 'number' }
}
}
}
}
}
}
}
},
'/api/datos-tabla/{idTabla}': {
get: {
tags: ['Datos'],
summary: 'Obtener datos de una tabla',
description: 'Devuelve los datos de una tabla específica del INE',
parameters: [
{
name: 'idTabla',
in: 'path',
required: true,
schema: { type: 'string' },
description: 'ID de la tabla',
example: '50902'
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' },
description: 'Idioma de la respuesta'
},
{
name: 'nult',
in: 'query',
schema: { type: 'integer' },
description: 'Número de últimos periodos'
},
{
name: 'det',
in: 'query',
schema: { type: 'integer', enum: [0, 1, 2] },
description: 'Nivel de detalle'
},
{
name: 'tip',
in: 'query',
schema: { type: 'string', enum: ['A', 'M', 'AM'] },
description: 'Tipo de respuesta (A=amigable, M=metadatos, AM=ambos)'
}
],
responses: {
'200': {
description: 'Datos de la tabla',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
success: { type: 'boolean' },
data: { type: 'object' }
}
}
}
}
}
}
}
},
'/api/datos-serie/{idSerie}': {
get: {
tags: ['Datos'],
summary: 'Obtener datos de una serie',
description: 'Devuelve los datos de una serie específica del INE',
parameters: [
{
name: 'idSerie',
in: 'path',
required: true,
schema: { type: 'string' },
description: 'ID de la serie',
example: 'IPC251856'
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
{
name: 'nult',
in: 'query',
schema: { type: 'integer' }
},
{
name: 'det',
in: 'query',
schema: { type: 'integer', enum: [0, 1, 2] }
}
],
responses: {
'200': { description: 'Datos de la serie' }
}
}
},
'/api/operaciones-disponibles': {
get: {
tags: ['Operaciones'],
summary: 'Listar operaciones disponibles',
description: 'Obtiene todas las operaciones estadísticas disponibles en el INE',
parameters: [
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
{
name: 'geo',
in: 'query',
schema: { type: 'integer', enum: [0, 1] },
description: '0=nacional, 1=geográfico'
},
{
name: 'page',
in: 'query',
schema: { type: 'integer' }
}
],
responses: {
'200': { description: 'Lista de operaciones' }
}
}
},
'/api/operacion/{idOperacion}': {
get: {
tags: ['Operaciones'],
summary: 'Obtener información de una operación',
parameters: [
{
name: 'idOperacion',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'IPC'
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
}
],
responses: {
'200': { description: 'Información de la operación' }
}
}
},
'/api/variables': {
get: {
tags: ['Variables'],
summary: 'Listar todas las variables',
parameters: [
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
{
name: 'page',
in: 'query',
schema: { type: 'integer' }
}
],
responses: {
'200': { description: 'Lista de variables' }
}
}
},
'/api/variables-operacion/{idOperacion}': {
get: {
tags: ['Variables'],
summary: 'Variables de una operación',
parameters: [
{
name: 'idOperacion',
in: 'path',
required: true,
schema: { type: 'string' }
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
}
],
responses: {
'200': { description: 'Variables de la operación' }
}
}
},
'/api/series-operacion/{idOperacion}': {
get: {
tags: ['Series'],
summary: 'Series de una operación',
parameters: [
{
name: 'idOperacion',
in: 'path',
required: true,
schema: { type: 'string' }
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
},
{
name: 'page',
in: 'query',
schema: { type: 'integer' }
}
],
responses: {
'200': { description: 'Series de la operación' }
}
}
},
'/api/tablas-operacion/{idOperacion}': {
get: {
tags: ['Tablas'],
summary: 'Tablas de una operación',
parameters: [
{
name: 'idOperacion',
in: 'path',
required: true,
schema: { type: 'string' }
},
{
name: 'idioma',
in: 'query',
schema: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }
}
],
responses: {
'200': { description: 'Tablas de la operación' }
}
}
},
'/health': {
get: {
tags: ['MCP'],
summary: 'Health check',
description: 'Verifica el estado del servidor',
responses: {
'200': {
description: 'Servidor funcionando',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
status: { type: 'string', example: 'ok' },
timestamp: { type: 'string', format: 'date-time' }
}
}
}
}
}
}
}
}
},
components: {
schemas: {
Error: {
type: 'object',
properties: {
success: { type: 'boolean', example: false },
error: { type: 'string' }
}
}
}
}
};

174
src/types/ine.types.ts Archivo normal
Ver fichero

@@ -0,0 +1,174 @@
/**
* Tipos para la API del INE
*/
export type Idioma = 'ES' | 'EN';
export interface INEBaseParams {
det?: 0 | 1 | 2;
tip?: 'A' | 'M' | 'AM';
}
export interface DatosTablaParams extends INEBaseParams {
nult?: number;
tv?: string;
date?: string;
}
export interface DatosSerieParams extends INEBaseParams {
nult?: number;
date?: string;
}
export interface DatosMetadataOperacionParams extends INEBaseParams {
p?: number;
nult?: number;
g1?: string;
g2?: string;
g3?: string;
g4?: string;
g5?: string;
}
export interface OperacionesDisponiblesParams extends INEBaseParams {
geo?: 0 | 1;
page?: number;
}
export interface OperacionParams extends INEBaseParams {}
export interface VariablesParams {
page?: number;
}
export interface VariablesOperacionParams {
page?: number;
}
export interface ValoresVariableParams extends INEBaseParams {
clasif?: number;
}
export interface ValoresVariableOperacionParams extends INEBaseParams {}
export interface TablasOperacionParams extends INEBaseParams {
geo?: 0 | 1;
tip?: 'A';
}
export interface ValoresGruposTablaParams extends INEBaseParams {}
export interface SerieParams extends INEBaseParams {
tip?: 'A' | 'M' | 'AM';
}
export interface SeriesOperacionParams extends INEBaseParams {
tip?: 'A' | 'M' | 'AM';
page?: number;
}
export interface ValoresSerieParams extends INEBaseParams {}
export interface SeriesTablaParams extends INEBaseParams {
tip?: 'A' | 'M' | 'AM';
tv?: string;
}
export interface SerieMetadataOperacionParams extends INEBaseParams {
p?: number;
tip?: 'A' | 'M' | 'AM';
g1?: string;
g2?: string;
g3?: string;
g4?: string;
g5?: string;
}
export interface PublicacionesParams extends INEBaseParams {
tip?: 'A';
}
export interface PublicacionesOperacionParams extends INEBaseParams {
tip?: 'A';
}
export interface PublicacionFechaPublicacionParams extends INEBaseParams {
tip?: 'A';
}
export interface ValoresHijosParams extends INEBaseParams {}
// Respuestas de la API
export interface INEResponse<T = any> {
data: T;
success: boolean;
error?: string;
}
export interface Operacion {
Id: number;
Codigo: string;
Nombre: string;
COD_IOE?: string;
}
export interface Variable {
Id: number;
Nombre: string;
Codigo?: string;
}
export interface Valor {
Id: number;
Nombre: string;
Codigo?: string;
Fk_Variable?: number;
}
export interface Serie {
COD: string;
Nombre: string;
FK_Operacion?: number;
FK_Periodicidad?: number;
FK_Publicacion?: number;
FK_Unidad?: number;
FK_Escala?: number;
}
export interface Tabla {
Id: number;
Nombre: string;
Codigo?: string;
FK_Operacion?: number;
FK_Periodicidad?: number;
}
export interface Dato {
Fecha: string;
Valor: number | string;
Anyo?: number;
NombrePeriodo?: string;
}
export interface Periodicidad {
Id: number;
Nombre: string;
Codigo?: string;
}
export interface Publicacion {
Id: number;
Nombre: string;
FK_Periodicidad?: number;
}
export interface Clasificacion {
Id: number;
Nombre: string;
Fecha?: string;
}
export interface Grupo {
Id: number;
Nombre: string;
}

19
start-server.sh Archivo ejecutable
Ver fichero

@@ -0,0 +1,19 @@
#!/bin/bash
# Script para iniciar el servidor MCP INE en modo HTTP
echo "🚀 Iniciando MCP INE Server (HTTP JSON-RPC)..."
# Verificar si está compilado
if [ ! -d "dist" ]; then
echo "📦 Compilando el proyecto..."
npm run build
fi
# Iniciar servidor
echo "🔧 Servidor escuchando en puerto 3000"
echo "📚 Documentación: http://localhost:3000/api-docs"
echo "🔌 Endpoint MCP: http://localhost:3000/mcp/v1"
echo ""
npm start

18
start-sse.sh Archivo ejecutable
Ver fichero

@@ -0,0 +1,18 @@
#!/bin/bash
# Script para iniciar el servidor MCP INE en modo SSE
echo "🚀 Iniciando MCP INE Server (SSE)..."
# Verificar si está compilado
if [ ! -d "dist" ]; then
echo "📦 Compilando el proyecto..."
npm run build
fi
# Iniciar servidor SSE
echo "🔧 Servidor SSE escuchando en puerto 3001"
echo "📡 Endpoint SSE: http://localhost:3001/sse"
echo ""
npm run start:sse

21
tsconfig.json Archivo normal
Ver fichero

@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"types": ["node"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}