@ssolis-ti/mcp-compra-agil 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +355 -0
  3. package/dist/api/compra-agil-client.d.ts +268 -0
  4. package/dist/api/compra-agil-client.d.ts.map +1 -0
  5. package/dist/api/compra-agil-client.js +137 -0
  6. package/dist/api/compra-agil-client.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +95 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/prompts/analizar-competencia.d.ts +9 -0
  12. package/dist/prompts/analizar-competencia.d.ts.map +1 -0
  13. package/dist/prompts/analizar-competencia.js +50 -0
  14. package/dist/prompts/analizar-competencia.js.map +1 -0
  15. package/dist/prompts/buscar-oportunidades.d.ts +9 -0
  16. package/dist/prompts/buscar-oportunidades.d.ts.map +1 -0
  17. package/dist/prompts/buscar-oportunidades.js +48 -0
  18. package/dist/prompts/buscar-oportunidades.js.map +1 -0
  19. package/dist/resources/compras-template.d.ts +10 -0
  20. package/dist/resources/compras-template.d.ts.map +1 -0
  21. package/dist/resources/compras-template.js +40 -0
  22. package/dist/resources/compras-template.js.map +1 -0
  23. package/dist/resources/documentacion.d.ts +6 -0
  24. package/dist/resources/documentacion.d.ts.map +1 -0
  25. package/dist/resources/documentacion.js +100 -0
  26. package/dist/resources/documentacion.js.map +1 -0
  27. package/dist/resources/estados.d.ts +9 -0
  28. package/dist/resources/estados.d.ts.map +1 -0
  29. package/dist/resources/estados.js +51 -0
  30. package/dist/resources/estados.js.map +1 -0
  31. package/dist/resources/glosario.d.ts +9 -0
  32. package/dist/resources/glosario.d.ts.map +1 -0
  33. package/dist/resources/glosario.js +77 -0
  34. package/dist/resources/glosario.js.map +1 -0
  35. package/dist/resources/regiones.d.ts +9 -0
  36. package/dist/resources/regiones.d.ts.map +1 -0
  37. package/dist/resources/regiones.js +37 -0
  38. package/dist/resources/regiones.js.map +1 -0
  39. package/dist/services/monitor.d.ts +2 -0
  40. package/dist/services/monitor.d.ts.map +1 -0
  41. package/dist/services/monitor.js +87 -0
  42. package/dist/services/monitor.js.map +1 -0
  43. package/dist/tools/auditar-desiertas.d.ts +4 -0
  44. package/dist/tools/auditar-desiertas.d.ts.map +1 -0
  45. package/dist/tools/auditar-desiertas.js +242 -0
  46. package/dist/tools/auditar-desiertas.js.map +1 -0
  47. package/dist/tools/buscar-compras.d.ts +10 -0
  48. package/dist/tools/buscar-compras.d.ts.map +1 -0
  49. package/dist/tools/buscar-compras.js +121 -0
  50. package/dist/tools/buscar-compras.js.map +1 -0
  51. package/dist/tools/detalle-compra.d.ts +10 -0
  52. package/dist/tools/detalle-compra.d.ts.map +1 -0
  53. package/dist/tools/detalle-compra.js +119 -0
  54. package/dist/tools/detalle-compra.js.map +1 -0
  55. package/dist/tools/detalle-oc.d.ts +10 -0
  56. package/dist/tools/detalle-oc.d.ts.map +1 -0
  57. package/dist/tools/detalle-oc.js +81 -0
  58. package/dist/tools/detalle-oc.js.map +1 -0
  59. package/dist/tools/documentos.d.ts +6 -0
  60. package/dist/tools/documentos.d.ts.map +1 -0
  61. package/dist/tools/documentos.js +245 -0
  62. package/dist/tools/documentos.js.map +1 -0
  63. package/dist/tools/estadisticas-uso.d.ts +10 -0
  64. package/dist/tools/estadisticas-uso.d.ts.map +1 -0
  65. package/dist/tools/estadisticas-uso.js +22 -0
  66. package/dist/tools/estadisticas-uso.js.map +1 -0
  67. package/dist/tools/generar-borrador.d.ts +4 -0
  68. package/dist/tools/generar-borrador.d.ts.map +1 -0
  69. package/dist/tools/generar-borrador.js +178 -0
  70. package/dist/tools/generar-borrador.js.map +1 -0
  71. package/dist/tools/monitorear-cambios.d.ts +10 -0
  72. package/dist/tools/monitorear-cambios.d.ts.map +1 -0
  73. package/dist/tools/monitorear-cambios.js +68 -0
  74. package/dist/tools/monitorear-cambios.js.map +1 -0
  75. package/dist/tools/radar-oportunidades.d.ts +4 -0
  76. package/dist/tools/radar-oportunidades.d.ts.map +1 -0
  77. package/dist/tools/radar-oportunidades.js +148 -0
  78. package/dist/tools/radar-oportunidades.js.map +1 -0
  79. package/dist/tools/recomendar-precio.d.ts +4 -0
  80. package/dist/tools/recomendar-precio.d.ts.map +1 -0
  81. package/dist/tools/recomendar-precio.js +180 -0
  82. package/dist/tools/recomendar-precio.js.map +1 -0
  83. package/dist/tools/verificar-oc.d.ts +13 -0
  84. package/dist/tools/verificar-oc.d.ts.map +1 -0
  85. package/dist/tools/verificar-oc.js +94 -0
  86. package/dist/tools/verificar-oc.js.map +1 -0
  87. package/dist/utils/env-loader.d.ts +6 -0
  88. package/dist/utils/env-loader.d.ts.map +1 -0
  89. package/dist/utils/env-loader.js +35 -0
  90. package/dist/utils/env-loader.js.map +1 -0
  91. package/dist/utils/error-handler.d.ts +28 -0
  92. package/dist/utils/error-handler.d.ts.map +1 -0
  93. package/dist/utils/error-handler.js +74 -0
  94. package/dist/utils/error-handler.js.map +1 -0
  95. package/dist/utils/logger.d.ts +15 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +48 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/rate-limiter.d.ts +39 -0
  100. package/dist/utils/rate-limiter.d.ts.map +1 -0
  101. package/dist/utils/rate-limiter.js +82 -0
  102. package/dist/utils/rate-limiter.js.map +1 -0
  103. package/package.json +53 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Cliente HTTP para la API REST de Compra Ágil v2 de Mercado Público.
3
+ *
4
+ * Centraliza autenticación, manejo de errores, rate limiting
5
+ * y paginación automática.
6
+ *
7
+ * Usa fetch nativo de Node.js 22+ (sin dependencias externas).
8
+ */
9
+ import { logger } from '../utils/logger.js';
10
+ import { handleApiResponse, CompraAgilApiError } from '../utils/error-handler.js';
11
+ import { RateLimiter } from '../utils/rate-limiter.js';
12
+ // ─── Cliente ────────────────────────────────────────────────────────
13
+ export class CompraAgilClient {
14
+ baseUrl;
15
+ ticket;
16
+ rateLimiter;
17
+ constructor(ticket, baseUrl) {
18
+ this.ticket = ticket;
19
+ this.baseUrl = baseUrl || 'https://api2.mercadopublico.cl';
20
+ this.rateLimiter = new RateLimiter();
21
+ }
22
+ /**
23
+ * Realiza un GET autenticado a la API.
24
+ */
25
+ async request(path, params) {
26
+ // Verificar rate limit antes de enviar
27
+ const limitCheck = this.rateLimiter.checkLimit();
28
+ if (limitCheck.limited) {
29
+ throw new CompraAgilApiError(429, [{
30
+ codigo: '429',
31
+ mensaje: `Cuota diaria agotada. Se restablece en ${limitCheck.resetIn}.`,
32
+ detalle: null,
33
+ }]);
34
+ }
35
+ // Construir URL con query params
36
+ const base = path.startsWith('/servicios') ? 'https://api.mercadopublico.cl' : this.baseUrl;
37
+ const url = new URL(path, base);
38
+ if (path.startsWith('/servicios')) {
39
+ url.searchParams.set('ticket', this.ticket);
40
+ }
41
+ if (params) {
42
+ for (const [key, value] of Object.entries(params)) {
43
+ if (value !== undefined && value !== null && value !== '') {
44
+ url.searchParams.set(key, String(value));
45
+ }
46
+ }
47
+ }
48
+ logger.debug(`API Request: GET ${url.toString()}`);
49
+ const response = await fetch(url.toString(), {
50
+ method: 'GET',
51
+ headers: {
52
+ 'ticket': this.ticket,
53
+ },
54
+ });
55
+ if (response.status === 429) {
56
+ this.rateLimiter.markLimited();
57
+ }
58
+ else {
59
+ this.rateLimiter.recordRequest();
60
+ }
61
+ const payload = await handleApiResponse(response);
62
+ return payload;
63
+ }
64
+ /**
65
+ * Buscar Compras Ágiles con filtros y paginación.
66
+ */
67
+ async buscar(params) {
68
+ const queryParams = {
69
+ ttl_cambio_ms: params.ttl_cambio_ms,
70
+ cambio_desde: params.cambio_desde,
71
+ cambio_hasta: params.cambio_hasta,
72
+ publicado_desde: params.publicado_desde,
73
+ publicado_hasta: params.publicado_hasta,
74
+ estado: params.estado,
75
+ region: params.region,
76
+ id: params.id,
77
+ q: params.q,
78
+ tamano_pagina: params.tamano_pagina,
79
+ numero_pagina: params.numero_pagina,
80
+ ordenar_por: params.ordenar_por,
81
+ };
82
+ return this.request('/v2/compra-agil', queryParams);
83
+ }
84
+ /**
85
+ * Buscar todas las páginas de resultados (auto-paginación).
86
+ * Útil cuando la IA necesita todos los resultados sin gestionar páginas.
87
+ */
88
+ async buscarTodo(params, maxPages = 10) {
89
+ const allItems = [];
90
+ let currentPage = 1;
91
+ while (currentPage <= maxPages) {
92
+ const response = await this.buscar({
93
+ ...params,
94
+ tamano_pagina: params.tamano_pagina || 50,
95
+ numero_pagina: currentPage,
96
+ });
97
+ allItems.push(...response.items);
98
+ logger.debug(`Auto-paginación: página ${response.paginacion.numero_pagina}/${response.paginacion.total_paginas}`);
99
+ if (currentPage >= response.paginacion.total_paginas) {
100
+ break;
101
+ }
102
+ currentPage++;
103
+ }
104
+ return allItems;
105
+ }
106
+ /**
107
+ * Obtener el detalle completo de una Compra Ágil específica.
108
+ */
109
+ async detalle(codigo) {
110
+ return this.request(`/v2/compra-agil/${encodeURIComponent(codigo)}`);
111
+ }
112
+ /**
113
+ * Buscar cambios recientes en los últimos N milisegundos.
114
+ */
115
+ async cambiosRecientes(ttlMs, filtros) {
116
+ return this.buscar({
117
+ ttl_cambio_ms: ttlMs,
118
+ ...filtros,
119
+ });
120
+ }
121
+ /**
122
+ * Obtener estadísticas del rate limiter.
123
+ */
124
+ getRateLimitStats() {
125
+ return this.rateLimiter.getStats();
126
+ }
127
+ /**
128
+ * Obtener el detalle completo de una Orden de Compra (OC).
129
+ * Admite tanto el ID numérico interno como el código alfanumérico.
130
+ */
131
+ async obtenerDetalleOC(idOC) {
132
+ return this.request('/servicios/v1/publico/OrdenCompra.json', {
133
+ codigo: String(idOC),
134
+ });
135
+ }
136
+ }
137
+ //# sourceMappingURL=compra-agil-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compra-agil-client.js","sourceRoot":"","sources":["../../src/api/compra-agil-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ import { loadEnvManual } from './utils/env-loader.js';
3
+ // Inicializar entorno antes de cualquier otra importación o llamada
4
+ loadEnvManual();
5
+ /**
6
+ * MCP Server: Compra Ágil v2 — Mercado Público de Chile
7
+ *
8
+ * Servidor MCP que envuelve la API REST de Compra Ágil v2,
9
+ * permitiendo a cualquier IA, agente o cliente MCP consultar
10
+ * procesos de compra pública del Estado de Chile.
11
+ *
12
+ * Transporte: Stdio (compatible con Claude Desktop, Cursor, OpenClaw, etc.)
13
+ */
14
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
15
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16
+ import { CompraAgilClient } from './api/compra-agil-client.js';
17
+ import { logger, setMcpServer } from './utils/logger.js';
18
+ // Tools
19
+ import { registerBuscarCompras } from './tools/buscar-compras.js';
20
+ import { registerDetalleCompra } from './tools/detalle-compra.js';
21
+ import { registerMonitorearCambios } from './tools/monitorear-cambios.js';
22
+ import { registerVerificarOC } from './tools/verificar-oc.js';
23
+ import { registerEstadisticasUso } from './tools/estadisticas-uso.js';
24
+ import { registerDetalleOC } from './tools/detalle-oc.js';
25
+ import { registerDocumentosTools } from './tools/documentos.js';
26
+ import { registerRecomendarPrecio } from './tools/recomendar-precio.js';
27
+ import { registerAuditarDesiertas } from './tools/auditar-desiertas.js';
28
+ import { registerGenerarBorrador } from './tools/generar-borrador.js';
29
+ import { registerRadarOportunidades } from './tools/radar-oportunidades.js';
30
+ // Resources
31
+ import { registerRegionesResource } from './resources/regiones.js';
32
+ import { registerEstadosResource } from './resources/estados.js';
33
+ import { registerGlosarioResource } from './resources/glosario.js';
34
+ import { registerComprasTemplateResource } from './resources/compras-template.js';
35
+ import { registerDocumentacionResource } from './resources/documentacion.js';
36
+ // Prompts
37
+ import { registerBuscarOportunidadesPrompt } from './prompts/buscar-oportunidades.js';
38
+ import { registerAnalizarCompetenciaPrompt } from './prompts/analizar-competencia.js';
39
+ // ─── Configuración ──────────────────────────────────────────────────
40
+ const TICKET = process.env.COMPRA_AGIL_TICKET;
41
+ const BASE_URL = process.env.COMPRA_AGIL_BASE_URL || 'https://api2.mercadopublico.cl';
42
+ if (!TICKET) {
43
+ logger.error('Variable de entorno COMPRA_AGIL_TICKET no configurada. ' +
44
+ 'Obtén tu ticket en https://www.chilecompra.cl/api/ y configúrala antes de iniciar el servidor.');
45
+ process.exit(1);
46
+ }
47
+ // Ticket validado — asignar a const tipada para usar dentro de main()
48
+ const VALID_TICKET = TICKET;
49
+ // ─── Inicialización ─────────────────────────────────────────────────
50
+ async function main() {
51
+ logger.info('Iniciando servidor MCP Compra Ágil v2...');
52
+ // 1. Crear cliente HTTP para la API de Mercado Público
53
+ const client = new CompraAgilClient(VALID_TICKET, BASE_URL);
54
+ logger.info(`Cliente API configurado → ${BASE_URL}`);
55
+ // 2. Crear servidor MCP
56
+ const server = new McpServer({
57
+ name: 'mcp-compra-agil',
58
+ version: '1.0.0',
59
+ });
60
+ // 3. Registrar herramientas (Tools)
61
+ registerBuscarCompras(server, client);
62
+ registerDetalleCompra(server, client);
63
+ registerMonitorearCambios(server, client);
64
+ registerVerificarOC(server, client);
65
+ registerEstadisticasUso(server, client);
66
+ registerDetalleOC(server, client);
67
+ registerDocumentosTools(server);
68
+ registerRecomendarPrecio(server, client);
69
+ registerAuditarDesiertas(server, client);
70
+ registerGenerarBorrador(server, client);
71
+ registerRadarOportunidades(server, client);
72
+ logger.info('13 herramientas registradas: buscar_compras_agiles, obtener_detalle_compra, monitorear_cambios_recientes, verificar_orden_compra, obtener_estadisticas_uso, obtener_detalle_orden_compra, obtener_enlace_documento, descargar_y_leer_documento, consultar_documentos_locales, recomendar_precio_ganador, auditar_compras_desiertas, generar_borrador_cotizacion, radar_oportunidades_calientes');
73
+ // 4. Registrar recursos (Resources)
74
+ registerRegionesResource(server);
75
+ registerEstadosResource(server);
76
+ registerGlosarioResource(server);
77
+ registerComprasTemplateResource(server, client);
78
+ registerDocumentacionResource(server);
79
+ logger.info('5 recursos registrados: regiones, estados, glosario, compra-agil://compras/{codigo}, compra-agil://documentacion/{filename}');
80
+ // 5. Registrar prompts
81
+ registerBuscarOportunidadesPrompt(server);
82
+ registerAnalizarCompetenciaPrompt(server);
83
+ logger.info('2 prompts registrados: buscar_oportunidades_proveedor, analizar_competencia');
84
+ // 6. Conectar al transporte Stdio
85
+ const transport = new StdioServerTransport();
86
+ await server.connect(transport);
87
+ // 7. Enlazar logger con la instancia del servidor conectado para logs nativos
88
+ setMcpServer(server);
89
+ logger.info('Servidor MCP Compra Ágil v2 listo y escuchando via Stdio.');
90
+ }
91
+ main().catch((error) => {
92
+ logger.error('Error fatal al iniciar el servidor MCP:', error);
93
+ process.exit(1);
94
+ });
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Prompt: analizar_competencia
3
+ *
4
+ * Plantilla guiada para que la IA analice la competencia
5
+ * en un proceso de Compra Ágil específico.
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ export declare function registerAnalizarCompetenciaPrompt(server: McpServer): void;
9
+ //# sourceMappingURL=analizar-competencia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analizar-competencia.d.ts","sourceRoot":"","sources":["../../src/prompts/analizar-competencia.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6CzE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Prompt: analizar_competencia
3
+ *
4
+ * Plantilla guiada para que la IA analice la competencia
5
+ * en un proceso de Compra Ágil específico.
6
+ */
7
+ import { z } from 'zod';
8
+ export function registerAnalizarCompetenciaPrompt(server) {
9
+ server.registerPrompt('analizar_competencia', {
10
+ description: 'Analiza la competencia en un proceso de Compra Ágil específico. Compara proveedores, precios, y genera insights sobre la competitividad del proceso.',
11
+ argsSchema: {
12
+ codigo: z.string().describe('Código de la Compra Ágil a analizar. Ej: "1057539-228-COT26".'),
13
+ },
14
+ }, async (args) => ({
15
+ messages: [
16
+ {
17
+ role: 'user',
18
+ content: {
19
+ type: 'text',
20
+ text: `Necesito un análisis competitivo del proceso de Compra Ágil con código "${args.codigo}".
21
+
22
+ Por favor, sigue estos pasos:
23
+
24
+ 1. **Obtener el detalle completo:** Usa "obtener_detalle_compra" con el código "${args.codigo}".
25
+
26
+ 2. **Verificar estado de OC:** Usa "verificar_orden_compra" para saber si ya se emitió una Orden de Compra.
27
+
28
+ 3. **Analizar los proveedores cotizando:**
29
+ - Lista todos los proveedores con sus montos totales, valores netos y costos de despacho.
30
+ - Identifica cuáles son Empresa de Menor Tamaño (EMT).
31
+ - Si hay productos cotizados, compara los precios unitarios entre proveedores.
32
+
33
+ 4. **Generar análisis comparativo:**
34
+ - Tabla comparativa de todos los proveedores:
35
+ | Proveedor | RUT | EMT | Valor Neto | Impuesto | Despacho | Total |
36
+ - Identifica al proveedor más económico y al más caro.
37
+ - Calcula el spread (diferencia porcentual entre el más barato y el más caro).
38
+ - Si hay precios unitarios, identifica en qué productos hay mayor diferencia de precio.
39
+
40
+ 5. **Conclusiones:**
41
+ - ¿El proceso es muy competitivo (muchos proveedores) o poco competitivo?
42
+ - ¿El presupuesto disponible es coherente con las ofertas recibidas?
43
+ - ¿Qué proveedor tiene la mejor relación precio-completitud?
44
+ - Si se seleccionó un proveedor, ¿fue el más barato o hay otros criterios?`,
45
+ },
46
+ },
47
+ ],
48
+ }));
49
+ }
50
+ //# sourceMappingURL=analizar-competencia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analizar-competencia.js","sourceRoot":"","sources":["../../src/prompts/analizar-competencia.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,cAAc,CACnB,sBAAsB,EACtB;QACE,WAAW,EAAE,sJAAsJ;QACnK,UAAU,EAAE;YACV,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;SAC7F;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACf,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,2EAA2E,IAAI,CAAC,MAAM;;;;kFAItB,IAAI,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;8EAoBf;iBACnE;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Prompt: buscar_oportunidades_proveedor
3
+ *
4
+ * Plantilla guiada para que la IA ayude a un proveedor
5
+ * a encontrar oportunidades de negocio en Compra Ágil.
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ export declare function registerBuscarOportunidadesPrompt(server: McpServer): void;
9
+ //# sourceMappingURL=buscar-oportunidades.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buscar-oportunidades.d.ts","sourceRoot":"","sources":["../../src/prompts/buscar-oportunidades.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2CzE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Prompt: buscar_oportunidades_proveedor
3
+ *
4
+ * Plantilla guiada para que la IA ayude a un proveedor
5
+ * a encontrar oportunidades de negocio en Compra Ágil.
6
+ */
7
+ import { z } from 'zod';
8
+ export function registerBuscarOportunidadesPrompt(server) {
9
+ server.registerPrompt('buscar_oportunidades_proveedor', {
10
+ description: 'Ayuda a un proveedor a encontrar oportunidades de Compra Ágil relevantes para su rubro y región. Genera un resumen ejecutivo con las mejores oportunidades, presupuestos y plazos.',
11
+ argsSchema: {
12
+ rubro: z.string().describe('Rubro o tipo de productos/servicios del proveedor. Ej: "materiales eléctricos", "servicios de limpieza", "equipos médicos".'),
13
+ region: z.string().describe('Región de interés del proveedor. Puede ser el nombre (ej: "Metropolitana") o el código numérico (ej: "13").'),
14
+ },
15
+ }, async (args) => ({
16
+ messages: [
17
+ {
18
+ role: 'user',
19
+ content: {
20
+ type: 'text',
21
+ text: `Soy un proveedor del rubro "${args.rubro}" y me interesa encontrar oportunidades de Compra Ágil en la región "${args.region}".
22
+
23
+ Por favor, sigue estos pasos:
24
+
25
+ 1. **Resolver la región:** Consulta el recurso "compra-agil://regiones" para obtener el código numérico de la región "${args.region}" si es que proporcioné el nombre.
26
+
27
+ 2. **Buscar oportunidades abiertas:** Usa la herramienta "buscar_compras_agiles" con:
28
+ - estado: "publicada" (solo procesos abiertos recibiendo cotizaciones)
29
+ - region: el código numérico resuelto
30
+ - q: "${args.rubro}" como palabras clave
31
+ - tamano_pagina: 50
32
+
33
+ 3. **Analizar los resultados:** Para los 5 procesos más relevantes (por presupuesto o afinidad), usa "obtener_detalle_compra" para obtener:
34
+ - Productos solicitados con cantidades
35
+ - Presupuesto disponible
36
+ - Fecha de cierre (plazo para cotizar)
37
+ - Dirección y plazo de entrega
38
+ - Número de competidores (ofertas recibidas)
39
+
40
+ 4. **Generar resumen ejecutivo:** Presenta una tabla con:
41
+ | Código | Nombre | Presupuesto CLP | Cierre | Productos | Competidores |
42
+ Y una recomendación sobre las mejores oportunidades considerando presupuesto alto, pocos competidores y afinidad con mi rubro.`,
43
+ },
44
+ },
45
+ ],
46
+ }));
47
+ }
48
+ //# sourceMappingURL=buscar-oportunidades.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buscar-oportunidades.js","sourceRoot":"","sources":["../../src/prompts/buscar-oportunidades.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,cAAc,CACnB,gCAAgC,EAChC;QACE,WAAW,EAAE,oLAAoL;QACjM,UAAU,EAAE;YACV,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6HAA6H,CAAC;YACzJ,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6GAA6G,CAAC;SAC3I;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACf,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,+BAA+B,IAAI,CAAC,KAAK,wEAAwE,IAAI,CAAC,MAAM;;;;wHAItB,IAAI,CAAC,MAAM;;;;;WAKxH,IAAI,CAAC,KAAK;;;;;;;;;;;;kIAY6G;iBACvH;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Resource: compra-agil://compras/{codigo}
3
+ *
4
+ * Recurso dinámico que permite consultar la ficha detallada de una Compra Ágil
5
+ * directamente mediante lectura de URI del protocolo MCP.
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ import { CompraAgilClient } from '../api/compra-agil-client.js';
9
+ export declare function registerComprasTemplateResource(server: McpServer, client: CompraAgilClient): void;
10
+ //# sourceMappingURL=compras-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compras-template.d.ts","sourceRoot":"","sources":["../../src/resources/compras-template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAoCjG"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Resource: compra-agil://compras/{codigo}
3
+ *
4
+ * Recurso dinámico que permite consultar la ficha detallada de una Compra Ágil
5
+ * directamente mediante lectura de URI del protocolo MCP.
6
+ */
7
+ import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ import { CompraAgilApiError } from '../utils/error-handler.js';
9
+ export function registerComprasTemplateResource(server, client) {
10
+ // Crear plantilla de URI para compra-agil://compras/{codigo}
11
+ const template = new ResourceTemplate('compra-agil://compras/{codigo}', {
12
+ list: undefined, // No implementamos listado dinámico masivo para evitar saturar la cuota de la API
13
+ });
14
+ server.registerResource('detalle-compra-dinamica', template, {
15
+ description: 'Obtiene el detalle completo de un proceso de Compra Ágil por su código único (formato XXXXXX-YYY-COTXX) en formato JSON estructurado.',
16
+ mimeType: 'application/json',
17
+ }, async (uri, variables) => {
18
+ try {
19
+ const codigo = variables.codigo;
20
+ if (!codigo) {
21
+ throw new Error('El parámetro "codigo" es requerido en la URI.');
22
+ }
23
+ const detalle = await client.detalle(codigo);
24
+ return {
25
+ contents: [{
26
+ uri: uri.toString(),
27
+ mimeType: 'application/json',
28
+ text: JSON.stringify(detalle, null, 2),
29
+ }],
30
+ };
31
+ }
32
+ catch (error) {
33
+ const message = error instanceof CompraAgilApiError
34
+ ? error.actionableMessage
35
+ : `Error al leer recurso de Compra Ágil: ${String(error)}`;
36
+ throw new Error(message);
37
+ }
38
+ });
39
+ }
40
+ //# sourceMappingURL=compras-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compras-template.js","sourceRoot":"","sources":["../../src/resources/compras-template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,UAAU,+BAA+B,CAAC,MAAiB,EAAE,MAAwB;IACzF,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,gCAAgC,EAAE;QACtE,IAAI,EAAE,SAAS,EAAE,kFAAkF;KACpG,CAAC,CAAC;IAEH,MAAM,CAAC,gBAAgB,CACrB,yBAAyB,EACzB,QAAQ,EACR;QACE,WAAW,EAAE,uIAAuI;QACpJ,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,MAAgB,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO;gBACL,QAAQ,EAAE,CAAC;wBACT,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;wBACnB,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;qBACvC,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,kBAAkB;gBACjD,CAAC,CAAC,KAAK,CAAC,iBAAiB;gBACzB,CAAC,CAAC,yCAAyC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Registra el recurso dinámico para consultar manuales y guías locales (PDF/TXT/MD).
4
+ */
5
+ export declare function registerDocumentacionResource(server: McpServer): void;
6
+ //# sourceMappingURL=documentacion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentacion.d.ts","sourceRoot":"","sources":["../../src/resources/documentacion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAoCtF;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsErE"}
@@ -0,0 +1,100 @@
1
+ import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { PDFParse } from 'pdf-parse';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const packageDocsDir = path.resolve(__dirname, '../../docs');
8
+ const cwdDocsDir = path.resolve(process.cwd(), 'docs');
9
+ let DOCS_DIR = cwdDocsDir;
10
+ if (fs.existsSync(packageDocsDir) && fs.readdirSync(packageDocsDir).some(f => f.toLowerCase().endsWith('.pdf'))) {
11
+ DOCS_DIR = packageDocsDir;
12
+ }
13
+ /**
14
+ * Obtiene de forma recursiva todos los archivos dentro de un directorio,
15
+ * retornando sus rutas relativas formateadas con barras diagonales (/).
16
+ */
17
+ function getRelativeFilesRecursively(dir, baseDir = dir) {
18
+ let results = [];
19
+ if (!fs.existsSync(dir))
20
+ return [];
21
+ const list = fs.readdirSync(dir);
22
+ for (const file of list) {
23
+ const filePath = path.join(dir, file);
24
+ const stat = fs.statSync(filePath);
25
+ if (stat && stat.isDirectory()) {
26
+ results = results.concat(getRelativeFilesRecursively(filePath, baseDir));
27
+ }
28
+ else {
29
+ const relativePath = path.relative(baseDir, filePath).replace(/\\/g, '/');
30
+ results.push(relativePath);
31
+ }
32
+ }
33
+ return results;
34
+ }
35
+ /**
36
+ * Registra el recurso dinámico para consultar manuales y guías locales (PDF/TXT/MD).
37
+ */
38
+ export function registerDocumentacionResource(server) {
39
+ // Crear plantilla de URI para compra-agil://documentacion/{filename}
40
+ const template = new ResourceTemplate('compra-agil://documentacion/{filename}', {
41
+ list: async () => {
42
+ try {
43
+ if (!fs.existsSync(DOCS_DIR)) {
44
+ fs.mkdirSync(DOCS_DIR, { recursive: true });
45
+ }
46
+ const files = getRelativeFilesRecursively(DOCS_DIR).filter(file => {
47
+ const ext = path.extname(file).toLowerCase();
48
+ const name = path.basename(file).toLowerCase();
49
+ return (ext === '.pdf' || ext === '.txt' || ext === '.md') && name !== 'readme.md';
50
+ });
51
+ return {
52
+ resources: files.map(file => ({
53
+ uri: `compra-agil://documentacion/${encodeURIComponent(file)}`,
54
+ name: file,
55
+ mimeType: 'text/plain', // Indicamos que el contenido entregado es de texto plano para que el LLM lo interprete
56
+ description: `Manual o Guía de Compra Ágil: ${file}`,
57
+ })),
58
+ };
59
+ }
60
+ catch (error) {
61
+ console.error('Error al listar recursos de documentación:', error);
62
+ return { resources: [] };
63
+ }
64
+ },
65
+ });
66
+ server.registerResource('documentacion-ayuda', template, {
67
+ description: 'Obtiene el contenido textual completo de una guía o manual local sobre Compra Ágil usando su nombre de archivo.',
68
+ mimeType: 'text/plain',
69
+ }, async (uri, variables) => {
70
+ try {
71
+ const filename = decodeURIComponent(variables.filename);
72
+ const filePath = path.join(DOCS_DIR, filename);
73
+ if (!fs.existsSync(filePath)) {
74
+ throw new Error(`El archivo ${filename} no existe en la carpeta docs/.`);
75
+ }
76
+ const ext = path.extname(filename).toLowerCase();
77
+ let text = '';
78
+ if (ext === '.pdf') {
79
+ const buffer = fs.readFileSync(filePath);
80
+ const parser = new PDFParse({ data: buffer });
81
+ const pdfData = await parser.getText();
82
+ text = pdfData.text || '';
83
+ }
84
+ else {
85
+ text = fs.readFileSync(filePath, 'utf8');
86
+ }
87
+ return {
88
+ contents: [{
89
+ uri: uri.toString(),
90
+ mimeType: 'text/plain',
91
+ text: text,
92
+ }],
93
+ };
94
+ }
95
+ catch (error) {
96
+ throw new Error(`Error al leer el manual local: ${error.message || String(error)}`);
97
+ }
98
+ });
99
+ }
100
+ //# sourceMappingURL=documentacion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentacion.js","sourceRoot":"","sources":["../../src/resources/documentacion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resource: compra-agil://estados
3
+ *
4
+ * Catálogo de estados válidos de una Compra Ágil con descripciones
5
+ * y notas sobre comportamiento real de la API.
6
+ */
7
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
+ export declare function registerEstadosResource(server: McpServer): void;
9
+ //# sourceMappingURL=estados.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estados.d.ts","sourceRoot":"","sources":["../../src/resources/estados.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmCpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgB/D"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Resource: compra-agil://estados
3
+ *
4
+ * Catálogo de estados válidos de una Compra Ágil con descripciones
5
+ * y notas sobre comportamiento real de la API.
6
+ */
7
+ const ESTADOS = [
8
+ {
9
+ codigo: 'publicada',
10
+ descripcion: 'La Compra Ágil está abierta y recibiendo cotizaciones de proveedores.',
11
+ nota: null,
12
+ },
13
+ {
14
+ codigo: 'cerrada',
15
+ descripcion: 'El plazo de cotización finalizó. El organismo está evaluando las ofertas.',
16
+ nota: null,
17
+ },
18
+ {
19
+ codigo: 'desierta',
20
+ descripcion: 'No se recibieron ofertas válidas para este proceso.',
21
+ nota: null,
22
+ },
23
+ {
24
+ codigo: 'cancelada',
25
+ descripcion: 'El proceso fue cancelado por el organismo comprador.',
26
+ nota: 'El motivo de cancelación está disponible en el campo motivos.motivo_cancelacion del detalle.',
27
+ },
28
+ {
29
+ codigo: 'proveedor_seleccionado',
30
+ descripcion: 'Se seleccionó al proveedor ganador. INCLUYE también las Compras Ágiles que ya tienen OC emitida.',
31
+ nota: 'Este estado agrupa tanto los procesos con proveedor elegido como los que ya tienen Orden de Compra. Para distinguirlos, usa la herramienta "verificar_orden_compra".',
32
+ },
33
+ {
34
+ codigo: 'oc_emitida',
35
+ descripcion: 'Se emitió una Orden de Compra (definido en el modelo de la API).',
36
+ nota: '⚠ LIMITACIÓN CONOCIDA: Este estado NO aparece en la práctica en las respuestas de la API. Los procesos con OC emitida se listan bajo "proveedor_seleccionado". Usa la herramienta "verificar_orden_compra" para detectar si un proceso tiene OC real.',
37
+ },
38
+ ];
39
+ export function registerEstadosResource(server) {
40
+ server.registerResource('estados', 'compra-agil://estados', {
41
+ description: 'Catálogo de estados válidos de una Compra Ágil con descripciones y notas sobre limitaciones conocidas de la API. Consulta este recurso antes de filtrar por estado para entender qué significa cada valor.',
42
+ mimeType: 'application/json',
43
+ }, async () => ({
44
+ contents: [{
45
+ uri: 'compra-agil://estados',
46
+ mimeType: 'application/json',
47
+ text: JSON.stringify(ESTADOS, null, 2),
48
+ }],
49
+ }));
50
+ }
51
+ //# sourceMappingURL=estados.js.map