some AI fixes

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-12-07 00:13:45 +01:00
padre ac67b3dc7c
commit 9305e359f0
Se han modificado 3 ficheros con 852 adiciones y 716 borrados

Ver fichero

@@ -6,11 +6,11 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { import {
CallToolRequestSchema, CallToolRequestSchema,
ListToolsRequestSchema, ListToolsRequestSchema
Tool
} from '@modelcontextprotocol/sdk/types.js'; } from '@modelcontextprotocol/sdk/types.js';
import { ineClient } from './services/ine-client.js'; import { ineClient } from './services/ine-client.js';
import { swaggerSpec } from './swagger.js'; import { swaggerSpec } from './swagger.js';
import { tools, SERVER_INFO, SERVER_INSTRUCTIONS } from './tools.js';
import type { Idioma } from './types/ine.types.js'; import type { Idioma } from './types/ine.types.js';
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
@@ -349,8 +349,8 @@ app.get('/health', (req: Request, res: Response) => {
res.json({ res.json({
status: 'ok', status: 'ok',
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
service: 'MCP INE Server', service: SERVER_INFO.name,
version: '1.0.0', version: SERVER_INFO.version,
tools: tools.length, tools: tools.length,
endpoints: { endpoints: {
mcp: '/mcp/v1', mcp: '/mcp/v1',
@@ -364,348 +364,6 @@ app.get('/health', (req: Request, res: Response) => {
}); });
}); });
/**
* 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 * Maneja las llamadas a las herramientas MCP
*/ */
@@ -796,8 +454,8 @@ async function handleToolCall(name: string, args: any): Promise<any> {
function createMCPServer(): Server { function createMCPServer(): Server {
const server = new Server( const server = new Server(
{ {
name: 'ine-mcp-server', name: SERVER_INFO.name,
version: '1.0.0', version: SERVER_INFO.version,
}, },
{ {
capabilities: { capabilities: {
@@ -861,12 +519,14 @@ app.post('/mcp/v1', async (req: Request, res: Response) => {
result: { result: {
protocolVersion: '2024-11-05', protocolVersion: '2024-11-05',
serverInfo: { serverInfo: {
name: 'ine-mcp-server', name: SERVER_INFO.name,
version: '1.0.0' version: SERVER_INFO.version,
description: SERVER_INFO.description
}, },
capabilities: { capabilities: {
tools: {} tools: {}
} },
instructions: SERVER_INSTRUCTIONS
}, },
id id
}); });

Ver fichero

@@ -7,6 +7,7 @@ import {
ListToolsRequestSchema ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js'; } from '@modelcontextprotocol/sdk/types.js';
import { ineClient } from './services/ine-client.js'; import { ineClient } from './services/ine-client.js';
import { tools, SERVER_INFO, SERVER_INSTRUCTIONS } from './tools.js';
import type { Idioma } from './types/ine.types.js'; import type { Idioma } from './types/ine.types.js';
const PORT = process.env.PORT || 3001; const PORT = process.env.PORT || 3001;
@@ -15,11 +16,14 @@ const app = express();
app.use(cors({ app.use(cors({
origin: '*', origin: '*',
methods: ['GET', 'POST', 'OPTIONS'], methods: ['GET', 'POST', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Accept'], allowedHeaders: ['Content-Type', 'Accept', 'Cache-Control'],
credentials: false credentials: false
})); }));
app.use(express.json()); app.use(express.json());
// Almacenar transportes SSE activos por sessionId
const sseTransports = new Map<string, SSEServerTransport>();
/** /**
* Maneja las llamadas a las herramientas MCP * Maneja las llamadas a las herramientas MCP
*/ */
@@ -80,348 +84,72 @@ async function handleToolCall(name: string, args: any): Promise<any> {
} }
} }
// Definición de herramientas (mismo que en index.ts) /**
const tools = [ * Página principal con información del servidor SSE
{ */
name: 'ine_datos_tabla', app.get('/', (req: Request, res: Response) => {
description: 'Obtiene datos de una tabla específica del INE. Permite filtrar por periodos, nivel de detalle y variables.', const baseUrl = req.protocol + '://' + req.get('host');
inputSchema: { res.send(`
type: 'object', <!DOCTYPE html>
properties: { <html lang="es">
idTabla: { type: 'string', description: 'ID de la tabla (ej: 50902)' }, <head>
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' }, <meta charset="UTF-8">
nult: { type: 'number', description: 'Número de últimos periodos' }, <meta name="viewport" content="width=device-width, initial-scale=1.0">
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }, <title>MCP INE Server (SSE)</title>
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Tipo: A=amigable, M=metadatos, AM=ambos' }, <style>
tv: { type: 'string', description: 'Filtro de variables (formato: id_variable:id_valor)' }, body { font-family: -apple-system, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
date: { type: 'string', description: 'Rango de fechas (formato: aaaammdd:aaaammdd)' } h1 { color: #667eea; }
}, code { background: #f0f0f0; padding: 2px 6px; border-radius: 3px; }
required: ['idTabla'] pre { background: #2d3748; color: #68d391; padding: 15px; border-radius: 6px; overflow-x: auto; }
} .endpoint { margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #667eea; }
}, </style>
{ </head>
name: 'ine_datos_serie', <body>
description: 'Obtiene datos de una serie temporal específica del INE.', <h1>🚀 MCP INE Server (SSE)</h1>
inputSchema: { <p>Servidor MCP con transporte SSE (Server-Sent Events) para acceder a los datos del INE.</p>
type: 'object',
properties: { <h2>Endpoints</h2>
idSerie: { type: 'string', description: 'Código de la serie (ej: IPC251856)' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }, <div class="endpoint">
nult: { type: 'number', description: 'Número de últimos periodos' }, <h3>GET /sse</h3>
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }, <p>Establecer conexión SSE para recibir mensajes del servidor MCP.</p>
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Tipo de respuesta' }, <pre>curl ${baseUrl}/sse</pre>
date: { type: 'string', description: 'Rango de fechas' } </div>
},
required: ['idSerie'] <div class="endpoint">
} <h3>POST /message</h3>
}, <p>Enviar mensajes JSON-RPC al servidor MCP.</p>
{ <pre>curl -X POST ${baseUrl}/message?sessionId=&lt;id&gt; \\
name: 'ine_datos_metadata_operacion', -H "Content-Type: application/json" \\
description: 'Obtiene datos de series usando filtros de metadata de una operación.', -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'</pre>
inputSchema: { </div>
type: 'object',
properties: { <div class="endpoint">
idOperacion: { type: 'string', description: 'Código de operación (ej: IPC)' }, <h3>GET /health</h3>
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES' }, <p>Estado del servidor.</p>
p: { type: 'number', description: 'Periodicidad (1=mensual, 3=trimestral, 12=anual)' }, <pre>curl ${baseUrl}/health</pre>
nult: { type: 'number', description: 'Número de últimos periodos' }, </div>
det: { type: 'number', enum: [0, 1, 2] },
tip: { type: 'string', enum: ['A', 'M', 'AM'] }, <h2>Configuración AI Toolkit (SSE)</h2>
g1: { type: 'string', description: 'Filtro 1 (formato: id_variable:id_valor)' }, <pre>{
g2: { type: 'string', description: 'Filtro 2' }, "mcpServers": {
g3: { type: 'string', description: 'Filtro 3' }, "mcp-ine-sse": {
g4: { type: 'string', description: 'Filtro 4' }, "url": "${baseUrl}/sse",
g5: { type: 'string', description: 'Filtro 5' } "transport": "sse"
},
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)' }
} }
} }
}, }</pre>
{
name: 'ine_operacion', <h2>Herramientas disponibles: ${tools.length}</h2>
description: 'Obtiene información detallada de una operación estadística.', <p>Usa <code>ine_operaciones_disponibles</code> para empezar a explorar los datos del INE.</p>
inputSchema: { </body>
type: 'object', </html>
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']
}
}
];
/** /**
* Endpoint SSE para conexión MCP * Endpoint SSE para conexión MCP
* Este endpoint establece la conexión SSE y retorna un sessionId para enviar mensajes
*/ */
app.get('/sse', async (req: Request, res: Response) => { app.get('/sse', async (req: Request, res: Response) => {
console.log('Nueva conexión SSE iniciada'); console.log('Nueva conexión SSE iniciada');
@@ -430,8 +158,8 @@ app.get('/sse', async (req: Request, res: Response) => {
// Crear servidor MCP // Crear servidor MCP
const server = new Server( const server = new Server(
{ {
name: 'ine-mcp-server-sse', name: SERVER_INFO.name + '-sse',
version: '1.0.0', version: SERVER_INFO.version,
}, },
{ {
capabilities: { capabilities: {
@@ -450,6 +178,7 @@ app.get('/sse', async (req: Request, res: Response) => {
const { name, arguments: args } = request.params; const { name, arguments: args } = request.params;
console.log(`SSE: CallTool request - ${name}`, args); console.log(`SSE: CallTool request - ${name}`, args);
try {
const result = await handleToolCall(name, args || {}); const result = await handleToolCall(name, args || {});
return { return {
@@ -460,11 +189,33 @@ app.get('/sse', async (req: Request, res: Response) => {
} }
] ]
}; };
} catch (error: any) {
console.error(`Error en herramienta ${name}:`, error);
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: true,
message: error.message,
tool: name
}, null, 2)
}
],
isError: true
};
}
}); });
// Crear transporte SSE - este configura los headers automáticamente // Crear transporte SSE - el segundo parámetro es el endpoint donde el cliente enviará mensajes
const transport = new SSEServerTransport('/message', res); const transport = new SSEServerTransport('/message', res);
// Guardar el transporte para poder recibir mensajes posteriormente
const sessionId = transport.sessionId;
sseTransports.set(sessionId, transport);
console.log(`SSE: Sesión creada con ID: ${sessionId}`);
// Conectar servidor con transporte // Conectar servidor con transporte
await server.connect(transport); await server.connect(transport);
@@ -472,7 +223,8 @@ app.get('/sse', async (req: Request, res: Response) => {
// Manejar cierre de conexión // Manejar cierre de conexión
req.on('close', () => { req.on('close', () => {
console.log('SSE: Conexión cerrada por el cliente'); console.log(`SSE: Conexión cerrada - sesión ${sessionId}`);
sseTransports.delete(sessionId);
server.close().catch(err => console.error('Error cerrando servidor:', err)); server.close().catch(err => console.error('Error cerrando servidor:', err));
}); });
@@ -488,23 +240,43 @@ app.get('/sse', async (req: Request, res: Response) => {
}); });
/** /**
* Endpoint para enviar mensajes (POST) * Endpoint para enviar mensajes al servidor MCP
* Este endpoint recibe los mensajes JSON-RPC del cliente * El cliente debe incluir el sessionId en el query string
*/ */
app.post('/message', express.json(), async (req: Request, res: Response) => { app.post('/message', async (req: Request, res: Response) => {
console.log('SSE Message received:', JSON.stringify(req.body, null, 2)); const sessionId = req.query.sessionId as string;
console.log(`SSE Message received for session ${sessionId}:`, JSON.stringify(req.body, null, 2));
if (!sessionId) {
return res.status(400).json({
error: 'sessionId is required',
message: 'Include ?sessionId=<id> in the URL. Get the sessionId from the SSE connection endpoint.'
});
}
const transport = sseTransports.get(sessionId);
if (!transport) {
return res.status(404).json({
error: 'Session not found',
message: `No active SSE session with id ${sessionId}. Establish a new connection via GET /sse.`,
activeSessions: Array.from(sseTransports.keys())
});
}
try { try {
// El SDK de MCP maneja esto internamente a través del SSEServerTransport // El SSEServerTransport maneja el mensaje internamente
// Solo necesitamos confirmar la recepción await transport.handlePostMessage(req, res);
res.status(202).json({ received: true });
} catch (error: any) { } catch (error: any) {
console.error('Error procesando mensaje SSE:', error); console.error('Error procesando mensaje SSE:', error);
if (!res.headersSent) {
res.status(500).json({ res.status(500).json({
error: error.message, error: error.message,
stack: error.stack stack: error.stack
}); });
} }
}
}); });
// Health check // Health check
@@ -513,8 +285,10 @@ app.get('/health', (req: Request, res: Response) => {
status: 'ok', status: 'ok',
transport: 'SSE', transport: 'SSE',
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
service: 'MCP INE Server (SSE)', service: SERVER_INFO.name + ' (SSE)',
version: '1.0.0', version: SERVER_INFO.version,
activeSessions: sseTransports.size,
tools: tools.length,
endpoints: { endpoints: {
sse: '/sse', sse: '/sse',
message: '/message', message: '/message',
@@ -526,5 +300,7 @@ app.get('/health', (req: Request, res: Response) => {
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`🚀 MCP INE Server (SSE) ejecutándose en http://localhost:${PORT}`); console.log(`🚀 MCP INE Server (SSE) ejecutándose en http://localhost:${PORT}`);
console.log(`📡 Endpoint SSE: http://localhost:${PORT}/sse`); console.log(`📡 Endpoint SSE: http://localhost:${PORT}/sse`);
console.log(`📨 Endpoint Message: http://localhost:${PORT}/message`);
console.log(`💚 Health check: http://localhost:${PORT}/health`); console.log(`💚 Health check: http://localhost:${PORT}/health`);
console.log(`📋 Herramientas disponibles: ${tools.length}`);
}); });

700
src/tools.ts Archivo normal
Ver fichero

@@ -0,0 +1,700 @@
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
/**
* Información del servidor MCP INE
*/
export const SERVER_INFO = {
name: 'mcp-ine',
version: '1.0.0',
description: `Servidor MCP para acceder a los datos del Instituto Nacional de Estadística (INE) de España.
El INE es el organismo oficial de estadística de España y ofrece datos sobre:
- Economía: IPC (inflación), PIB, comercio exterior, empresas
- Empleo: EPA (paro y empleo), salarios, condiciones de trabajo
- Población: censos, demografía, migraciones
- Sociedad: condiciones de vida, educación, salud
- Territorio: datos por CCAA, provincias, municipios
CÓMO USAR ESTE SERVIDOR:
1. Empieza con 'ine_operaciones_disponibles' para ver todas las estadísticas
2. Usa 'ine_tablas_operacion' con el código (ej: "IPC") para ver tablas disponibles
3. Usa 'ine_datos_tabla' con el ID de tabla para obtener los datos
OPERACIONES MÁS CONSULTADAS:
- IPC: Índice de Precios al Consumo (inflación mensual)
- EPA: Encuesta de Población Activa (empleo trimestral)
- PIB: Producto Interior Bruto
- CIFRAS_POB: Población oficial
- ECV: Encuesta de Condiciones de Vida
`
};
/**
* Instrucciones para el modelo sobre cómo usar el servidor
*/
export const SERVER_INSTRUCTIONS = `Este servidor proporciona acceso a los datos del Instituto Nacional de Estadística (INE) de España.
FLUJO DE TRABAJO RECOMENDADO:
1. Usa 'ine_operaciones_disponibles' para ver todas las operaciones estadísticas disponibles
2. Usa 'ine_tablas_operacion' con el código de operación (ej: "IPC", "EPA") para ver las tablas
3. Usa 'ine_datos_tabla' con el ID de tabla para obtener los datos concretos
OPERACIONES MÁS USADAS:
- IPC: Índice de Precios al Consumo (inflación) - Mensual
- EPA: Encuesta de Población Activa (empleo/paro) - Trimestral
- PIB: Producto Interior Bruto - Trimestral
- CIFRAS_POB: Cifras de Población - Semestral
- ECV: Encuesta de Condiciones de Vida - Anual
- DEFUNCIONES/NACIMIENTOS: Estadísticas vitales - Mensual
EJEMPLOS DE TABLAS COMUNES:
- Tabla 50902: IPC por grupos ECOICOP
- Tabla 4247: Población por provincias
- Tabla 4076: EPA - Tasas de paro
PARÁMETROS IMPORTANTES:
- nult: Número de últimos periodos (ej: nult=12 para último año)
- det: Nivel de detalle (0=básico, 2=completo)
- tip: Formato (A=amigable con nombres legibles)
- tv: Filtro por variable (formato: ID_VARIABLE:ID_VALOR)
- date: Rango de fechas (formato: AAAAMMDD:AAAAMMDD)`;
/**
* Definición de herramientas MCP para la API del INE (Instituto Nacional de Estadística de España)
*
* El INE ofrece datos estadísticos oficiales de España organizados en:
* - OPERACIONES: Estadísticas principales (IPC, EPA, PIB, Población, etc.)
* - TABLAS: Conjuntos de datos dentro de cada operación
* - SERIES: Series temporales con datos históricos
* - VARIABLES: Dimensiones de los datos (territorio, tiempo, actividad económica, etc.)
*
* OPERACIONES MÁS COMUNES:
* - IPC: Índice de Precios al Consumo (inflación)
* - EPA: Encuesta de Población Activa (empleo/paro)
* - PIB: Producto Interior Bruto (contabilidad nacional)
* - CIFRAS_POB: Cifras de Población
* - ECV: Encuesta de Condiciones de Vida
* - DEFUNCIONES: Estadística de Defunciones
* - NACIMIENTOS: Estadística de Nacimientos
* - COMERCIO_EXT: Comercio Exterior
* - TURISMO: Estadísticas de Turismo
*
* FLUJO DE TRABAJO RECOMENDADO:
* 1. Usar ine_operaciones_disponibles para ver todas las operaciones
* 2. Usar ine_operacion para obtener detalles de una operación específica
* 3. Usar ine_tablas_operacion para ver las tablas disponibles
* 4. Usar ine_datos_tabla para obtener los datos concretos
*/
export const tools: Tool[] = [
{
name: 'ine_datos_tabla',
description: `Obtiene los datos estadísticos de una tabla específica del INE.
EJEMPLOS DE TABLAS COMUNES:
- Tabla 50902: IPC por grupos ECOICOP (inflación por categorías)
- Tabla 4247: Población por provincias y sexo
- Tabla 4076: EPA - Tasas de paro por sexo y edad
- Tabla 30678: PIB a precios de mercado
PARÁMETROS:
- nult: Limita a los N últimos periodos (ej: nult=12 para último año mensual)
- det: Nivel de detalle (0=básico, 1=medio, 2=completo con metadatos)
- tip: Formato de respuesta (A=amigable con nombres, M=solo metadatos, AM=ambos)
- tv: Filtrar por variable (formato: ID_VARIABLE:ID_VALOR, ej: "3:6" para filtrar por Madrid)
- date: Rango de fechas (formato: AAAAMMDD:AAAAMMDD, ej: "20230101:20231231")
Para encontrar IDs de tablas, usa primero ine_tablas_operacion con el código de la operación (ej: "IPC").`,
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID numérico de la tabla (ej: "50902" para IPC por grupos, "4247" para población). Usa ine_tablas_operacion para encontrar IDs.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma de los resultados: ES=español, EN=inglés' },
nult: { type: 'number', description: 'Número de últimos periodos a obtener (ej: 12 para último año si es mensual, 4 para último año si es trimestral)' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle: 0=básico, 1=medio, 2=completo con todos los metadatos' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato: A=amigable (incluye nombres legibles), M=solo metadatos, AM=ambos' },
tv: { type: 'string', description: 'Filtro de variables (formato: ID_VARIABLE:ID_VALOR). Ej: "3:6" filtra por Madrid (variable 3=territorio, valor 6=Madrid)' },
date: { type: 'string', description: 'Rango de fechas (formato: AAAAMMDD:AAAAMMDD). Ej: "20230101:20231231" para todo 2023' }
},
required: ['idTabla']
}
},
{
name: 'ine_datos_serie',
description: `Obtiene los datos históricos de una serie temporal específica del INE.
Las series son conjuntos de datos a lo largo del tiempo para un indicador específico.
Cada serie tiene un código único que combina la operación y un identificador numérico.
EJEMPLOS DE SERIES:
- IPC251856: Índice general de precios al consumo (base 2021)
- EPA17: Tasa de paro total nacional
- DPOP163: Población total de España
PARÁMETROS:
- nult: Obtener solo los N últimos valores (ej: nult=24 para últimos 24 meses)
- date: Filtrar por rango de fechas
Para encontrar códigos de series, usa ine_series_operacion o ine_series_tabla.`,
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string', description: 'Código de la serie temporal (ej: "IPC251856" para IPC general). Usa ine_series_operacion para encontrar códigos.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma de los resultados' },
nult: { type: 'number', description: 'Número de últimos periodos a obtener' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle: 0=básico, 1=medio, 2=completo' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato: A=amigable, M=metadatos, AM=ambos' },
date: { type: 'string', description: 'Rango de fechas (formato: AAAAMMDD:AAAAMMDD)' }
},
required: ['idSerie']
}
},
{
name: 'ine_datos_metadata_operacion',
description: `Obtiene datos de series filtrando por metadatos de una operación estadística.
Permite hacer consultas avanzadas combinando múltiples filtros (hasta 5 grupos de filtrado).
Útil cuando necesitas datos específicos de una operación sin conocer los IDs de series.
EJEMPLO: Para obtener el IPC de alimentación en Madrid:
- idOperacion: "IPC"
- g1: "762:244074" (grupo ECOICOP: Alimentos y bebidas no alcohólicas)
- g2: "70:9264" (provincia: Madrid)
PERIODICIDADES COMUNES (parámetro p):
- 1: Mensual
- 3: Trimestral
- 6: Semestral
- 12: Anual
Para conocer los IDs de variables y valores, usa ine_variables_operacion y ine_valores_variable_operacion.`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA", "PIB"). Usa ine_operaciones_disponibles para ver todas.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma de los resultados' },
p: { type: 'number', description: 'Periodicidad: 1=mensual, 3=trimestral, 6=semestral, 12=anual' },
nult: { type: 'number', description: 'Número de últimos periodos a obtener' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato de respuesta' },
g1: { type: 'string', description: 'Filtro grupo 1 (formato: ID_VARIABLE:ID_VALOR)' },
g2: { type: 'string', description: 'Filtro grupo 2 (formato: ID_VARIABLE:ID_VALOR)' },
g3: { type: 'string', description: 'Filtro grupo 3 (formato: ID_VARIABLE:ID_VALOR)' },
g4: { type: 'string', description: 'Filtro grupo 4 (formato: ID_VARIABLE:ID_VALOR)' },
g5: { type: 'string', description: 'Filtro grupo 5 (formato: ID_VARIABLE:ID_VALOR)' }
},
required: ['idOperacion']
}
},
{
name: 'ine_operaciones_disponibles',
description: `HERRAMIENTA PRINCIPAL para descubrir todas las operaciones estadísticas del INE.
USA ESTA HERRAMIENTA PRIMERO para saber qué datos están disponibles.
OPERACIONES MÁS RELEVANTES:
- IPC: Índice de Precios al Consumo (inflación mensual)
- EPA: Encuesta de Población Activa (empleo/desempleo trimestral)
- PIB (o CNE): Contabilidad Nacional (PIB trimestral y anual)
- CIFRAS_POB: Cifras oficiales de población
- ECV: Encuesta de Condiciones de Vida
- DEFUNCIONES / NACIMIENTOS: Estadísticas vitales
- COMERCIO_EXT: Comercio exterior
- TURISMO: Estadísticas de turismo
- HIPOTECAS: Estadísticas de hipotecas
- SOCIEDADES: Estadísticas de sociedades mercantiles
La respuesta incluye el código de operación (campo "Codigo") que necesitarás para otras consultas.`,
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma de los resultados' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle: 0=básico (solo Id, Código, Nombre), 1=medio, 2=completo' },
geo: { type: 'number', enum: [0, 1], description: 'Tipo de operaciones: 0=estadísticas nacionales, 1=estadísticas con desagregación geográfica' },
page: { type: 'number', description: 'Número de página (cada página tiene 500 elementos). Por defecto página 1.' }
}
}
},
{
name: 'ine_operacion',
description: `Obtiene información detallada de una operación estadística específica.
Devuelve metadatos completos incluyendo:
- Nombre completo y descripción
- Periodicidad (mensual, trimestral, anual)
- Fecha de inicio de la serie
- Código IOE (clasificación internacional)
- Información sobre la publicación
EJEMPLOS DE CÓDIGOS:
- "IPC" → Índice de Precios al Consumo
- "EPA" → Encuesta de Población Activa
- "PIB" o "30678" → Producto Interior Bruto
- "CIFRAS_POB" → Cifras de Población
- "ECV" → Encuesta de Condiciones de Vida`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA") o su ID numérico. Usa ine_operaciones_disponibles para ver todas.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle: 0=básico, 1=medio, 2=completo' }
},
required: ['idOperacion']
}
},
{
name: 'ine_variables',
description: `Lista todas las variables estadísticas disponibles en el INE.
Las variables son las dimensiones que caracterizan los datos estadísticos.
VARIABLES MÁS COMUNES:
- ID 3 (Territorio): Provincias, CCAA, municipios
- ID 70 (Provincias): 52 provincias españolas
- ID 762 (Grupos ECOICOP): Categorías del IPC
- ID 547 (Sexo): Hombre, Mujer, Total
- ID 18 (Edad): Grupos de edad
- ID 349 (Actividad económica): Sectores CNAE
Estas variables se usan para filtrar datos con el parámetro 'tv' (formato: ID_VARIABLE:ID_VALOR).`,
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
page: { type: 'number', description: 'Página de resultados (500 por página)' }
}
}
},
{
name: 'ine_variables_operacion',
description: `Obtiene las variables (dimensiones) utilizadas en una operación específica.
Muy útil para saber qué filtros puedes aplicar a los datos de una operación.
EJEMPLO: Para el IPC, devuelve variables como:
- Grupos ECOICOP (categorías de productos)
- Índices y tasas (índice, variación mensual, anual)
- Tipo de dato (dato definitivo, provisional)
Para la EPA, devuelve:
- Sexo
- Grupo de edad
- Situación laboral
- Comunidad Autónoma
Usa el ID de la variable con ine_valores_variable_operacion para ver sus valores posibles.`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
page: { type: 'number', description: 'Página de resultados' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_variable',
description: `Obtiene todos los valores posibles de una variable estadística.
EJEMPLOS:
- Variable 70 (Provincias): Madrid (28), Barcelona (8), Valencia (46)...
- Variable 547 (Sexo): Hombres, Mujeres, Ambos sexos
- Variable 762 (Grupos ECOICOP): Alimentos, Vestido, Vivienda, Transporte...
- Variable 3 (Territorio): Comunidades autónomas y provincias
Los valores obtenidos (campo "Id") se usan para filtrar datos con el formato ID_VARIABLE:ID_VALOR.
Por ejemplo, para filtrar por Madrid:
- Variable 70 (provincias), Valor para Madrid = su ID específico
- Usar en filtro: "70:28" (si 28 es el ID de Madrid)`,
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string', description: 'ID numérico de la variable (ej: "70" para provincias, "547" para sexo). Usa ine_variables para ver todas.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
clasif: { type: 'number', description: 'ID de clasificación (opcional, para filtrar por clasificación específica)' }
},
required: ['idVariable']
}
},
{
name: 'ine_valores_variable_operacion',
description: `Obtiene los valores de una variable específica DENTRO del contexto de una operación.
Más preciso que ine_valores_variable porque solo devuelve valores relevantes para la operación.
EJEMPLO PRÁCTICO:
Para saber qué grupos de productos tiene el IPC:
- idOperacion: "IPC"
- idVariable: "762" (Grupos ECOICOP)
Resultado: Alimentos (Id: X), Vestido (Id: Y), Vivienda (Id: Z), etc.
Luego usa esos IDs para filtrar datos específicos.`,
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string', description: 'ID de la variable. Usa ine_variables_operacion para ver las variables de la operación.' },
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }
},
required: ['idVariable', 'idOperacion']
}
},
{
name: 'ine_tablas_operacion',
description: `Lista todas las tablas de datos disponibles para una operación estadística.
Esta herramienta es CLAVE para saber qué datos puedes obtener de una operación.
EJEMPLOS:
Para "IPC" devuelve tablas como:
- Índices por comunidades autónomas
- Índices por grupos ECOICOP
- Variaciones mensuales y anuales
- Índices por provincias
Para "EPA" devuelve tablas como:
- Activos por sexo y grupo de edad
- Parados por tiempo de búsqueda de empleo
- Ocupados por sector económico
- Tasas de actividad, empleo y paro
El campo "Id" de cada tabla se usa luego con ine_datos_tabla para obtener los datos.`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA", "PIB")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
geo: { type: 'number', enum: [0, 1], description: '0=tablas nacionales, 1=tablas con desagregación geográfica' },
tip: { type: 'string', enum: ['A'], description: 'A=formato amigable con nombres legibles' }
},
required: ['idOperacion']
}
},
{
name: 'ine_grupos_tabla',
description: `Obtiene los grupos de selección (dimensiones) que definen una tabla.
Cada tabla del INE está estructurada en grupos que determinan cómo se organizan los datos.
Esto te ayuda a entender la estructura de los datos antes de solicitarlos.
EJEMPLO: Una tabla del IPC puede tener grupos como:
- Grupo 1: Tipo de índice/variación
- Grupo 2: Grupos ECOICOP (categorías de productos)
- Grupo 3: Territorio
Usa el ID del grupo con ine_valores_grupos_tabla para ver sus valores posibles.`,
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID de la tabla. Usa ine_tablas_operacion para encontrar IDs de tablas.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' }
},
required: ['idTabla']
}
},
{
name: 'ine_valores_grupos_tabla',
description: `Obtiene los valores disponibles para un grupo específico dentro de una tabla.
Complementa a ine_grupos_tabla: primero obtienes los grupos, luego los valores de cada grupo.
EJEMPLO:
Si la tabla del IPC tiene un grupo "Territorio" (ID: 1), esta herramienta devuelve:
- Nacional
- Andalucía
- Aragón
- ... (todas las CCAA y provincias disponibles)`,
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID de la tabla' },
idGrupo: { type: 'string', description: 'ID del grupo (obtenido de ine_grupos_tabla)' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }
},
required: ['idTabla', 'idGrupo']
}
},
{
name: 'ine_serie',
description: `Obtiene información completa (metadatos) de una serie temporal específica.
A diferencia de ine_datos_serie (que devuelve los datos), esta herramienta devuelve los METADATOS:
- Nombre completo de la serie
- Periodicidad (mensual, trimestral, anual)
- Unidad de medida
- Escala
- Operación a la que pertenece
- Fecha de inicio y fin
Útil para entender qué representa una serie antes de pedir sus datos.`,
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string', description: 'Código de la serie (ej: "IPC251856")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato de respuesta' }
},
required: ['idSerie']
}
},
{
name: 'ine_series_operacion',
description: `Lista todas las series temporales disponibles para una operación.
Puede devolver MUCHAS series (algunas operaciones tienen miles).
Usa el parámetro 'page' para paginar si es necesario.
EJEMPLO: Para "IPC" devuelve series como:
- IPC251856: Índice general nacional
- IPC251857: Índice de alimentos
- IPC251858: Índice de vestido
- ... y muchas más por territorio y categoría
Cada serie tiene un código (campo "COD") que puedes usar con ine_datos_serie.`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato: A=amigable con nombres' },
page: { type: 'number', description: 'Página de resultados (importante para operaciones con muchas series)' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_serie',
description: `Obtiene las variables y sus valores que definen una serie específica.
Explica QUÉ REPRESENTA la serie mostrando sus dimensiones.
EJEMPLO: Para una serie del IPC de alimentación en Madrid:
- Variable "Grupo ECOICOP": Valor "Alimentos y bebidas no alcohólicas"
- Variable "Territorio": Valor "Madrid"
- Variable "Tipo de dato": Valor "Índice"
Útil para entender exactamente qué datos contiene una serie.`,
inputSchema: {
type: 'object',
properties: {
idSerie: { type: 'string', description: 'Código de la serie' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }
},
required: ['idSerie']
}
},
{
name: 'ine_series_tabla',
description: `Obtiene todas las series temporales contenidas en una tabla específica.
Relaciona tablas con series: una tabla puede contener múltiples series.
EJEMPLO: La tabla de IPC por comunidades autónomas contiene series para:
- Cada comunidad autónoma
- Cada tipo de índice
- Cada período
Puedes filtrar las series con el parámetro 'tv' (formato: ID_VARIABLE:ID_VALOR).`,
inputSchema: {
type: 'object',
properties: {
idTabla: { type: 'string', description: 'ID de la tabla' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato de respuesta' },
tv: { type: 'string', description: 'Filtro por variable (formato: ID_VARIABLE:ID_VALOR)' }
},
required: ['idTabla']
}
},
{
name: 'ine_serie_metadata_operacion',
description: `Busca series temporales usando filtros de metadatos dentro de una operación.
Similar a ine_datos_metadata_operacion pero devuelve SERIES en lugar de datos.
Útil para encontrar códigos de series específicas antes de pedir sus datos.
EJEMPLO: Para encontrar la serie del IPC de transporte en Barcelona:
- idOperacion: "IPC"
- g1: "762:244082" (grupo ECOICOP: Transporte)
- g2: "70:8" (provincia: Barcelona)
La respuesta incluirá el código de la serie que coincide con esos filtros.`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
p: { type: 'number', description: 'Periodicidad: 1=mensual, 3=trimestral, 12=anual' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A', 'M', 'AM'], description: 'Formato de respuesta' },
g1: { type: 'string', description: 'Filtro grupo 1 (formato: ID_VARIABLE:ID_VALOR)' },
g2: { type: 'string', description: 'Filtro grupo 2' },
g3: { type: 'string', description: 'Filtro grupo 3' },
g4: { type: 'string', description: 'Filtro grupo 4' },
g5: { type: 'string', description: 'Filtro grupo 5' }
},
required: ['idOperacion']
}
},
{
name: 'ine_periodicidades',
description: `Lista todas las periodicidades disponibles en el INE.
PERIODICIDADES COMUNES:
- 1: Mensual (IPC, paro registrado)
- 3: Trimestral (EPA, PIB)
- 6: Semestral
- 12: Anual (censos, encuestas estructurales)
Cada estadística tiene una periodicidad que indica con qué frecuencia se publican nuevos datos.`,
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' }
}
}
},
{
name: 'ine_publicaciones',
description: `Lista todas las publicaciones estadísticas disponibles del INE.
Las publicaciones son documentos/informes que agrupan y presentan los datos de las operaciones.
Cada publicación tiene una fecha de difusión programada.
EJEMPLOS:
- Índice de Precios de Consumo (publicación mensual)
- Encuesta de Población Activa (publicación trimestral)
- Cifras de Población (publicación semestral)
Usa ine_publicacion_fecha_publicacion para ver las fechas de publicación.`,
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A'], description: 'A=formato amigable' }
}
}
},
{
name: 'ine_publicaciones_operacion',
description: `Obtiene las publicaciones asociadas a una operación estadística específica.
Una operación puede tener múltiples publicaciones con diferentes periodicidades o enfoques.
EJEMPLO: La operación "IPC" tiene publicaciones como:
- Índices nacionales mensuales
- Índices por comunidades autónomas
- Variaciones interanuales
- Notas de prensa`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A'], description: 'A=formato amigable' }
},
required: ['idOperacion']
}
},
{
name: 'ine_publicacion_fecha_publicacion',
description: `Obtiene las fechas de difusión (calendario de publicación) para una publicación estadística.
Muestra cuándo se han publicado y se publicarán nuevos datos.
Útil para saber cuándo habrá datos actualizados disponibles.
Incluye:
- Fechas de publicaciones pasadas
- Fechas programadas de próximas publicaciones`,
inputSchema: {
type: 'object',
properties: {
idPublicacion: { type: 'string', description: 'ID de la publicación. Usa ine_publicaciones o ine_publicaciones_operacion para obtener IDs.' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' },
tip: { type: 'string', enum: ['A'], description: 'A=formato amigable' }
},
required: ['idPublicacion']
}
},
{
name: 'ine_clasificaciones',
description: `Lista todas las clasificaciones estadísticas utilizadas por el INE.
Las clasificaciones son sistemas jerárquicos para organizar datos.
CLASIFICACIONES COMUNES:
- CNAE: Clasificación Nacional de Actividades Económicas
- ECOICOP: Clasificación del consumo (usada en el IPC)
- CNO: Clasificación Nacional de Ocupaciones
- NUTS: Nomenclatura de Unidades Territoriales
- CIE: Clasificación Internacional de Enfermedades
Cada clasificación tiene múltiples niveles de detalle.`,
inputSchema: {
type: 'object',
properties: {
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' }
}
}
},
{
name: 'ine_clasificaciones_operacion',
description: `Obtiene las clasificaciones utilizadas en una operación estadística específica.
Muestra qué sistemas de clasificación se usan para organizar los datos de esa operación.
EJEMPLOS:
- IPC usa ECOICOP (clasificación de productos de consumo)
- EPA usa CNO (clasificación de ocupaciones) y CNAE (actividades económicas)
- Comercio Exterior usa CNAE y clasificaciones arancelarias`,
inputSchema: {
type: 'object',
properties: {
idOperacion: { type: 'string', description: 'Código de la operación (ej: "IPC", "EPA")' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' }
},
required: ['idOperacion']
}
},
{
name: 'ine_valores_hijos',
description: `Obtiene valores hijos en una estructura jerárquica de una variable.
Muchas variables del INE tienen estructuras de árbol (padre-hijo).
EJEMPLOS:
- Territorio: España → Comunidades Autónomas → Provincias → Municipios
- Actividad económica: Sector → División → Grupo → Clase
- Grupos ECOICOP: Grupo principal → Subgrupos
CASO DE USO:
Para obtener las provincias de Andalucía:
- idVariable: "70" (provincias/territorio)
- idValor: ID de Andalucía
Resultado: Almería, Cádiz, Córdoba, Granada, Huelva, Jaén, Málaga, Sevilla`,
inputSchema: {
type: 'object',
properties: {
idVariable: { type: 'string', description: 'ID de la variable jerárquica' },
idValor: { type: 'string', description: 'ID del valor padre del que quieres obtener los hijos' },
idioma: { type: 'string', enum: ['ES', 'EN'], default: 'ES', description: 'Idioma' },
det: { type: 'number', enum: [0, 1, 2], description: 'Nivel de detalle' }
},
required: ['idVariable', 'idValor']
}
}
];