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

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;
}