@ssolis-ti/mcp-compra-agil 1.0.3 → 2.3.0

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 (121) hide show
  1. package/README.md +111 -23
  2. package/dist/api/compra-agil-client.d.ts +37 -2
  3. package/dist/api/compra-agil-client.d.ts.map +1 -1
  4. package/dist/api/compra-agil-client.js +76 -5
  5. package/dist/api/compra-agil-client.js.map +1 -1
  6. package/dist/index.js +32 -8
  7. package/dist/index.js.map +1 -1
  8. package/dist/reports/components.d.ts +59 -0
  9. package/dist/reports/components.d.ts.map +1 -0
  10. package/dist/reports/components.js +125 -0
  11. package/dist/reports/components.js.map +1 -0
  12. package/dist/reports/export.d.ts +27 -0
  13. package/dist/reports/export.d.ts.map +1 -0
  14. package/dist/reports/export.js +47 -0
  15. package/dist/reports/export.js.map +1 -0
  16. package/dist/reports/format.d.ts +24 -0
  17. package/dist/reports/format.d.ts.map +1 -0
  18. package/dist/reports/format.js +74 -0
  19. package/dist/reports/format.js.map +1 -0
  20. package/dist/reports/render.d.ts +18 -0
  21. package/dist/reports/render.d.ts.map +1 -0
  22. package/dist/reports/render.js +30 -0
  23. package/dist/reports/render.js.map +1 -0
  24. package/dist/reports/templates/radar-oportunidades.d.ts +41 -0
  25. package/dist/reports/templates/radar-oportunidades.d.ts.map +1 -0
  26. package/dist/reports/templates/radar-oportunidades.js +170 -0
  27. package/dist/reports/templates/radar-oportunidades.js.map +1 -0
  28. package/dist/reports/theme.d.ts +83 -0
  29. package/dist/reports/theme.d.ts.map +1 -0
  30. package/dist/reports/theme.js +284 -0
  31. package/dist/reports/theme.js.map +1 -0
  32. package/dist/resources/compras-template.d.ts.map +1 -1
  33. package/dist/resources/compras-template.js +2 -1
  34. package/dist/resources/compras-template.js.map +1 -1
  35. package/dist/resources/documentacion.d.ts.map +1 -1
  36. package/dist/resources/documentacion.js +5 -36
  37. package/dist/resources/documentacion.js.map +1 -1
  38. package/dist/resources/estados.d.ts.map +1 -1
  39. package/dist/resources/estados.js +24 -10
  40. package/dist/resources/estados.js.map +1 -1
  41. package/dist/services/monitor.js +38 -3
  42. package/dist/services/monitor.js.map +1 -1
  43. package/dist/tools/analizar-precios-mercado.d.ts +21 -0
  44. package/dist/tools/analizar-precios-mercado.d.ts.map +1 -0
  45. package/dist/tools/analizar-precios-mercado.js +217 -0
  46. package/dist/tools/analizar-precios-mercado.js.map +1 -0
  47. package/dist/tools/auditar-desiertas.d.ts.map +1 -1
  48. package/dist/tools/auditar-desiertas.js +66 -48
  49. package/dist/tools/auditar-desiertas.js.map +1 -1
  50. package/dist/tools/buscar-compras.d.ts.map +1 -1
  51. package/dist/tools/buscar-compras.js +2 -1
  52. package/dist/tools/buscar-compras.js.map +1 -1
  53. package/dist/tools/detalle-compra.d.ts.map +1 -1
  54. package/dist/tools/detalle-compra.js +6 -5
  55. package/dist/tools/detalle-compra.js.map +1 -1
  56. package/dist/tools/detalle-oc.js +6 -6
  57. package/dist/tools/detalle-oc.js.map +1 -1
  58. package/dist/tools/documentos.d.ts.map +1 -1
  59. package/dist/tools/documentos.js +75 -81
  60. package/dist/tools/documentos.js.map +1 -1
  61. package/dist/tools/estadisticas-uso.d.ts.map +1 -1
  62. package/dist/tools/estadisticas-uso.js +12 -2
  63. package/dist/tools/estadisticas-uso.js.map +1 -1
  64. package/dist/tools/generar-borrador.d.ts +25 -1
  65. package/dist/tools/generar-borrador.d.ts.map +1 -1
  66. package/dist/tools/generar-borrador.js +111 -82
  67. package/dist/tools/generar-borrador.js.map +1 -1
  68. package/dist/tools/generar-informe.d.ts +13 -0
  69. package/dist/tools/generar-informe.d.ts.map +1 -0
  70. package/dist/tools/generar-informe.js +111 -0
  71. package/dist/tools/generar-informe.js.map +1 -0
  72. package/dist/tools/monitorear-cambios.d.ts +32 -2
  73. package/dist/tools/monitorear-cambios.d.ts.map +1 -1
  74. package/dist/tools/monitorear-cambios.js +79 -10
  75. package/dist/tools/monitorear-cambios.js.map +1 -1
  76. package/dist/tools/radar-oportunidades.d.ts +42 -1
  77. package/dist/tools/radar-oportunidades.d.ts.map +1 -1
  78. package/dist/tools/radar-oportunidades.js +123 -103
  79. package/dist/tools/radar-oportunidades.js.map +1 -1
  80. package/dist/tools/recomendar-precio.d.ts +13 -0
  81. package/dist/tools/recomendar-precio.d.ts.map +1 -1
  82. package/dist/tools/recomendar-precio.js +53 -57
  83. package/dist/tools/recomendar-precio.js.map +1 -1
  84. package/dist/tools/verificar-oc.d.ts.map +1 -1
  85. package/dist/tools/verificar-oc.js +36 -8
  86. package/dist/tools/verificar-oc.js.map +1 -1
  87. package/dist/tools/verificar-ticket.d.ts +13 -0
  88. package/dist/tools/verificar-ticket.d.ts.map +1 -0
  89. package/dist/tools/verificar-ticket.js +79 -0
  90. package/dist/tools/verificar-ticket.js.map +1 -0
  91. package/dist/utils/cache.d.ts +53 -0
  92. package/dist/utils/cache.d.ts.map +1 -0
  93. package/dist/utils/cache.js +131 -0
  94. package/dist/utils/cache.js.map +1 -0
  95. package/dist/utils/doc-search.d.ts +52 -0
  96. package/dist/utils/doc-search.d.ts.map +1 -0
  97. package/dist/utils/doc-search.js +97 -0
  98. package/dist/utils/doc-search.js.map +1 -0
  99. package/dist/utils/docs-locator.d.ts +41 -0
  100. package/dist/utils/docs-locator.d.ts.map +1 -0
  101. package/dist/utils/docs-locator.js +82 -0
  102. package/dist/utils/docs-locator.js.map +1 -0
  103. package/dist/utils/error-handler.d.ts.map +1 -1
  104. package/dist/utils/error-handler.js +8 -7
  105. package/dist/utils/error-handler.js.map +1 -1
  106. package/dist/utils/logger.d.ts.map +1 -1
  107. package/dist/utils/logger.js +9 -6
  108. package/dist/utils/logger.js.map +1 -1
  109. package/dist/utils/quotation.d.ts +71 -0
  110. package/dist/utils/quotation.d.ts.map +1 -0
  111. package/dist/utils/quotation.js +140 -0
  112. package/dist/utils/quotation.js.map +1 -0
  113. package/dist/utils/rate-limiter.d.ts +44 -2
  114. package/dist/utils/rate-limiter.d.ts.map +1 -1
  115. package/dist/utils/rate-limiter.js +125 -13
  116. package/dist/utils/rate-limiter.js.map +1 -1
  117. package/dist/utils/redact.d.ts +48 -0
  118. package/dist/utils/redact.d.ts.map +1 -0
  119. package/dist/utils/redact.js +100 -0
  120. package/dist/utils/redact.js.map +1 -0
  121. package/package.json +55 -53
@@ -1,43 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
- import { fileURLToPath } from 'url';
5
4
  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
- /**
10
- * Obtiene de forma recursiva todos los archivos dentro de un directorio,
11
- * retornando sus rutas relativas formateadas con barras diagonales (/).
12
- */
13
- function getRelativeFilesRecursively(dir, baseDir = dir) {
14
- let results = [];
15
- if (!fs.existsSync(dir))
16
- return [];
17
- const list = fs.readdirSync(dir);
18
- for (const file of list) {
19
- const filePath = path.join(dir, file);
20
- const stat = fs.statSync(filePath);
21
- if (stat && stat.isDirectory()) {
22
- results = results.concat(getRelativeFilesRecursively(filePath, baseDir));
23
- }
24
- else {
25
- const relativePath = path.relative(baseDir, filePath).replace(/\\/g, '/');
26
- results.push(relativePath);
27
- }
28
- }
29
- return results;
30
- }
31
- let DOCS_DIR = cwdDocsDir;
32
- if (fs.existsSync(packageDocsDir)) {
33
- const hasLocalDocs = getRelativeFilesRecursively(packageDocsDir).some(file => {
34
- const ext = path.extname(file).toLowerCase();
35
- return ext === '.pdf' || ext === '.txt' || ext === '.md';
36
- });
37
- if (hasLocalDocs) {
38
- DOCS_DIR = packageDocsDir;
39
- }
40
- }
5
+ import { resolveDocsDir, listSupportedDocs } from '../utils/docs-locator.js';
6
+ import { buscarEnTexto } from '../utils/doc-search.js';
7
+ import { safeError } from '../utils/redact.js';
8
+ const DOCS_DIR = resolveDocsDir();
41
9
  /**
42
10
  * Registra las herramientas relacionadas con documentos y especificaciones en el servidor MCP.
43
11
  */
@@ -61,18 +29,23 @@ export function registerDocumentosTools(server) {
61
29
  };
62
30
  }
63
31
  else {
32
+ // Verificado en septiembre 2026: este endpoint heredado responde 404
33
+ // para los adjuntos de Compra Ágil, aun con IDs numéricos válidos
34
+ // entregados por la API. Se sigue ofreciendo por si el portal lo
35
+ // restablece, pero la ficha va primero y sin prometer que funcionará.
64
36
  const directUrl = `https://www.mercadopublico.cl/FichaLicitacion/RetornaDocumento.aspx?id=${args.id_documento}`;
65
37
  return {
66
38
  content: [{
67
39
  type: 'text',
68
- text: `Este documento es de tipo tradicional (ID numérico) y se puede descargar directamente.\n\nEnlace de descarga directa:\n${directUrl}\n\nEnlace alternativo a la ficha pública del proceso:\n${fichaUrl}`,
40
+ text: `Para acceder al adjunto ${args.id_documento}, abre la ficha pública del proceso (no requiere iniciar sesión):\n${fichaUrl}\n\nExiste además un enlace heredado de descarga directa, pero se comprobó que hoy responde 404 para los adjuntos de Compra Ágil, así que probablemente no funcione:\n${directUrl}`,
69
41
  }],
70
42
  };
71
43
  }
72
44
  });
73
45
  // ─── 2. DESCARGAR Y LEER DOCUMENTO DE PROCESO (REMOTO) ───────────────
74
46
  server.registerTool('descargar_y_leer_documento', {
75
- description: 'Descarga un documento adjunto de Mercado Público (bases técnicas/administrativas) en formato PDF usando su ID, extrae su texto y lo retorna al LLM. Útil para auditar requisitos técnicos de una oferta.',
47
+ description: `Intenta descargar un adjunto de Compra Ágil (bases técnicas/administrativas) y extraer su texto.
48
+ ⚠ IMPORTANTE: para los IDs numéricos —que son los que entrega esta API— el portal ya NO sirve el archivo, así que la herramienta responde de inmediato con el enlace a la ficha pública en vez de intentar una descarga que se sabe fallida. Si necesitas las especificaciones para cotizar, tendrás que abrir esa ficha en un navegador: el enlace del adjunto lo genera JavaScript y no existe una URL que un programa pueda pedir.`,
76
49
  inputSchema: {
77
50
  id_documento: z.string().describe('ID único del documento. Ej: "123456" o un UUID.'),
78
51
  codigo_compra: z.string().optional().describe('Código de la Compra Ágil asociada (Ej: "2494-141-COT26"). Permite guiar al usuario a la ficha pública en caso de fallar la descarga.'),
@@ -82,29 +55,58 @@ export function registerDocumentosTools(server) {
82
55
  }, async (args) => {
83
56
  try {
84
57
  const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(args.id_documento);
85
- const url = isUuid
86
- ? `https://adjunto.mercadopublico.cl/adjunto-compra-agil/descargar/${args.id_documento}`
87
- : `https://www.mercadopublico.cl/FichaLicitacion/RetornaDocumento.aspx?id=${args.id_documento}`;
58
+ // ⚠ NO se intenta la descarga de IDs numéricos: se comprobó que el
59
+ // endpoint heredado responde 404 para todos los adjuntos de Compra
60
+ // Ágil (IDs 1855508 y 1854909, de procesos distintos), y la causa es
61
+ // estructural — en la ficha el enlace es un <a> con href vacío, la
62
+ // descarga la dispara JavaScript y no hay URL estática que pedir.
63
+ // Gastar una petición y esperar su timeout para confirmar un fallo
64
+ // conocido solo retrasa la única respuesta útil, que es el enlace.
65
+ //
66
+ // Los UUID SÍ se intentan: usan otro endpoint (adjunto.mercadopublico.cl)
67
+ // que nunca se pudo ejercitar, así que no se da por muerto sin prueba.
68
+ // Si algún día vuelven a servirse los numéricos, `scripts/debug-*.ts`
69
+ // y esta guarda son el punto por donde revertirlo.
70
+ if (!isUuid) {
71
+ const ficha = args.codigo_compra
72
+ ? `\n\nÁbrelo desde la ficha pública del proceso (en un navegador, sin iniciar sesión):\nhttps://buscador.mercadopublico.cl/ficha?code=${args.codigo_compra}`
73
+ : '\n\nBusca el código de la compra en https://buscador.mercadopublico.cl y abre su ficha para ver el adjunto.';
74
+ return {
75
+ content: [{
76
+ type: 'text',
77
+ text: `El adjunto ${args.id_documento} no se puede descargar por programa: Mercado Público dejó de servir los adjuntos de Compra Ágil por enlace directo, y en la ficha el archivo se descarga mediante JavaScript, sin una URL que se pueda pedir.${ficha}\n\nSi necesitas las especificaciones técnicas para cotizar, suelen estar solo en ese adjunto, así que conviene abrirlo ahí.`,
78
+ }],
79
+ };
80
+ }
81
+ const url = `https://adjunto.mercadopublico.cl/adjunto-compra-agil/descargar/${args.id_documento}`;
88
82
  // Descargar PDF
89
83
  const response = await fetch(url, {
90
84
  headers: {
91
85
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
92
86
  }
93
87
  });
94
- if (response.status === 403 || response.status === 401) {
88
+ // ⚠ 404 se trata igual que 401/403 y no como un fallo inesperado:
89
+ // verificado contra el servicio real (septiembre 2026) que el endpoint
90
+ // heredado RetornaDocumento.aspx responde 404 para los adjuntos de
91
+ // Compra Ágil, incluso con IDs numéricos entregados por la propia API
92
+ // (probados 1855508 y 1854909, de procesos distintos). Para el usuario
93
+ // la situación práctica es la misma que un bloqueo: hay que ir a la
94
+ // ficha. Devolver un "Error HTTP 404" pelado hacía que el modelo
95
+ // informara una falla técnica en vez de la vía alternativa que sí sirve.
96
+ if (!response.ok) {
95
97
  const fichaMsg = args.codigo_compra
96
- ? `\n\nPor favor, descarga el archivo de forma pública e independiente desde la ficha del proceso en el buscador de Mercado Público:\nhttps://buscador.mercadopublico.cl/ficha?code=${args.codigo_compra}`
97
- : '\n\nPor favor, descarga el archivo manualmente buscando el código de la compra en el buscador público de Mercado Público.';
98
+ ? `\n\nDescarga el archivo desde la ficha pública del proceso (se abre en el navegador, sin iniciar sesión):\nhttps://buscador.mercadopublico.cl/ficha?code=${args.codigo_compra}`
99
+ : '\n\nBusca el código de la compra en https://buscador.mercadopublico.cl para descargar el archivo desde su ficha.';
100
+ const causa = response.status === 404
101
+ ? `el portal ya no expone este adjunto por descarga directa (HTTP 404). Es el comportamiento observado para los adjuntos de Compra Ágil, no un error de tu consulta`
102
+ : `el servidor de Mercado Público requiere autenticación (Clave Única) o bloquea las solicitudes programáticas (HTTP ${response.status})`;
98
103
  return {
99
104
  content: [{
100
105
  type: 'text',
101
- text: `No es posible descargar ni procesar este archivo de forma automática porque el servidor de Mercado Público requiere autenticación (Clave Única) o bloquea las solicitudes programáticas (HTTP ${response.status}).${fichaMsg}`,
106
+ text: `No fue posible descargar el documento ${args.id_documento} automáticamente: ${causa}.${fichaMsg}\n\nSi necesitas las especificaciones técnicas para cotizar, ábrelo desde ese enlace: suelen estar solo en el adjunto.`,
102
107
  }],
103
108
  };
104
109
  }
105
- if (!response.ok) {
106
- throw new Error(`Error HTTP al intentar descargar el documento: ${response.status} ${response.statusText}`);
107
- }
108
110
  const arrayBuffer = await response.arrayBuffer();
109
111
  const buffer = Buffer.from(arrayBuffer);
110
112
  // Parsear PDF
@@ -166,7 +168,7 @@ export function registerDocumentosTools(server) {
166
168
  return {
167
169
  content: [{
168
170
  type: 'text',
169
- text: `Error al procesar el documento remoto: ${error.message || String(error)}`,
171
+ text: `Error al procesar el documento remoto: ${safeError(error)}`,
170
172
  }],
171
173
  isError: true,
172
174
  };
@@ -176,7 +178,7 @@ export function registerDocumentosTools(server) {
176
178
  server.registerTool('consultar_documentos_locales', {
177
179
  description: 'Busca y lee información dentro de los manuales, normativas o guías de Compra Ágil almacenados localmente en la carpeta docs/ (soporta formatos .pdf, .txt, .md).',
178
180
  inputSchema: {
179
- query: z.string().optional().describe('Término de búsqueda para filtrar fragmentos del documento (ej: "monto", "criterios"). Si se omite, lista los documentos disponibles.'),
181
+ query: z.string().optional().describe('Qué buscar. Admite tanto un término suelto ("multas", "garantía") como una pregunta en lenguaje natural ("¿qué multas me pueden aplicar?"): la consulta se descompone en términos y se ignoran acentos y palabras vacías. Si se omite, lista los documentos disponibles.'),
180
182
  max_caracteres: z.number().min(500).max(15000).default(3000).optional().describe('Cantidad máxima de texto a retornar de cada coincidencia.'),
181
183
  },
182
184
  }, async (args) => {
@@ -184,11 +186,7 @@ export function registerDocumentosTools(server) {
184
186
  if (!fs.existsSync(DOCS_DIR)) {
185
187
  fs.mkdirSync(DOCS_DIR, { recursive: true });
186
188
  }
187
- const files = getRelativeFilesRecursively(DOCS_DIR).filter(file => {
188
- const ext = path.extname(file).toLowerCase();
189
- const name = path.basename(file).toLowerCase();
190
- return (ext === '.pdf' || ext === '.txt' || ext === '.md') && name !== 'readme.md';
191
- });
189
+ const files = listSupportedDocs(DOCS_DIR);
192
190
  if (files.length === 0) {
193
191
  return {
194
192
  content: [{
@@ -210,8 +208,11 @@ export function registerDocumentosTools(server) {
210
208
  }],
211
209
  };
212
210
  }
213
- const searchTerm = args.query.toLowerCase();
214
211
  const results = [];
212
+ // Términos que sí aparecieron en algún documento, para poder explicar
213
+ // un resultado vacío en vez de afirmar que no existe información.
214
+ const terminosEncontrados = new Set();
215
+ let terminosConsulta = [];
215
216
  for (const file of files) {
216
217
  const filePath = path.join(DOCS_DIR, file);
217
218
  const ext = path.extname(file).toLowerCase();
@@ -226,39 +227,32 @@ export function registerDocumentosTools(server) {
226
227
  else {
227
228
  fileText = fs.readFileSync(filePath, 'utf8');
228
229
  }
229
- if (fileText.toLowerCase().includes(searchTerm)) {
230
- // Buscar fragmentos relevantes
231
- const lines = fileText.split('\n');
232
- const fileMatches = [];
233
- for (let i = 0; i < lines.length; i++) {
234
- const line = lines[i]?.trim();
235
- if (line && line.toLowerCase().includes(searchTerm)) {
236
- const context = [];
237
- if (i > 0 && lines[i - 1]?.trim())
238
- context.push(`[Anterior] ${lines[i - 1]?.trim()}`);
239
- context.push(`[COINCIDENCIA] ${line}`);
240
- if (i < lines.length - 1 && lines[i + 1]?.trim())
241
- context.push(`[Siguiente] ${lines[i + 1]?.trim()}`);
242
- fileMatches.push(context.join('\n'));
243
- }
244
- }
245
- if (fileMatches.length > 0) {
246
- const limit = args.max_caracteres || 3000;
247
- const matchesText = fileMatches.join('\n\n---\n\n');
248
- const truncated = matchesText.length > limit ? `${matchesText.substring(0, limit)}... [TRUNCADO]` : matchesText;
249
- results.push(`### Archivo: ${file}\n\n${truncated}`);
250
- }
230
+ const hallazgo = buscarEnTexto(fileText, args.query);
231
+ terminosConsulta = hallazgo.terminos;
232
+ for (const f of hallazgo.fragmentos) {
233
+ for (const t of f.terminos)
234
+ terminosEncontrados.add(t);
235
+ }
236
+ if (hallazgo.fragmentos.length > 0) {
237
+ const limit = args.max_caracteres || 3000;
238
+ const matchesText = hallazgo.fragmentos.map((f) => f.texto).join('\n\n---\n\n');
239
+ const truncated = matchesText.length > limit ? `${matchesText.substring(0, limit)}... [TRUNCADO]` : matchesText;
240
+ const cubiertos = [...new Set(hallazgo.fragmentos.flatMap((f) => f.terminos))];
241
+ results.push(`### Archivo: ${file}\n(términos encontrados aquí: ${cubiertos.join(', ')})\n\n${truncated}`);
251
242
  }
252
243
  }
253
244
  catch (e) {
254
- results.push(`### Archivo: ${file}\nError al leer o parsear: ${e.message || String(e)}`);
245
+ results.push(`### Archivo: ${file}\nError al leer o parsear: ${safeError(e)}`);
255
246
  }
256
247
  }
257
248
  if (results.length === 0) {
249
+ const detalle = terminosConsulta.length > 0
250
+ ? `\n\nLa consulta se buscó como los términos: ${terminosConsulta.join(', ')}. Ninguno aparece en los documentos. Prueba con sinónimos o con un término más general.`
251
+ : '';
258
252
  return {
259
253
  content: [{
260
254
  type: 'text',
261
- text: `No se encontraron coincidencias para "${args.query}" en ninguno de los ${files.length} documentos locales en "docs/".`,
255
+ text: `No se encontraron coincidencias para "${args.query}" en ninguno de los ${files.length} documentos locales en "docs/".${detalle}`,
262
256
  }],
263
257
  };
264
258
  }
@@ -273,7 +267,7 @@ export function registerDocumentosTools(server) {
273
267
  return {
274
268
  content: [{
275
269
  type: 'text',
276
- text: `Error al consultar documentos locales: ${error.message || String(error)}`,
270
+ text: `Error al consultar documentos locales: ${safeError(error)}`,
277
271
  }],
278
272
  isError: true,
279
273
  };
@@ -1 +1 @@
1
- {"version":3,"file":"documentos.js","sourceRoot":"","sources":["../../src/tools/documentos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documentos.js","sourceRoot":"","sources":["../../src/tools/documentos.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"estadisticas-uso.d.ts","sourceRoot":"","sources":["../../src/tools/estadisticas-uso.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAgBzF"}
1
+ {"version":3,"file":"estadisticas-uso.d.ts","sourceRoot":"","sources":["../../src/tools/estadisticas-uso.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAMhE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAyBzF"}
@@ -5,16 +5,26 @@
5
5
  * para la API de Compra Ágil de Mercado Público.
6
6
  */
7
7
  const TOOL_NAME = 'obtener_estadisticas_uso';
8
- const TOOL_DESCRIPTION = 'Obtiene las estadísticas de uso de la API y el estado actual de la cuota diaria (Rate Limiting). Útil para que el agente supervise cuántos requests quedan disponibles.';
8
+ const TOOL_DESCRIPTION = `Informa cuántas consultas a la API lleva hecha esta instalación en el día UTC en curso, y si ya se recibió un 429 por cuota agotada.
9
+ IMPORTANTE: es un conteo LOCAL, no el saldo oficial del ticket. La API no publica cuánta cuota queda, y el ticket puede estar siendo consumido también por otras herramientas o equipos. Sirve para moderar el gasto, no para afirmar cuántas consultas quedan.`;
9
10
  export function registerEstadisticasUso(server, client) {
10
11
  server.registerTool(TOOL_NAME, {
11
12
  description: TOOL_DESCRIPTION,
12
13
  }, async () => {
13
14
  const stats = client.getRateLimitStats();
15
+ const salida = {
16
+ _alcance: 'Conteo local de esta instalación para el día UTC en curso. La API no expone el saldo real del ticket; si otras herramientas usan el mismo ticket, el consumo real es mayor que este número.',
17
+ requests_hechos_hoy: stats.requestsToday,
18
+ cuota_agotada: stats.isLimited,
19
+ reset_estimado: stats.resetTime,
20
+ _nota: stats.isLimited
21
+ ? 'Se recibió un 429: la cuota diaria del ticket está agotada hasta el reset indicado. Evita nuevas consultas hasta entonces.'
22
+ : 'No se ha recibido ningún 429 en esta jornada. Eso NO garantiza que quede cuota: solo que esta instalación aún no ha chocado con el límite.',
23
+ };
14
24
  return {
15
25
  content: [{
16
26
  type: 'text',
17
- text: JSON.stringify(stats, null, 2),
27
+ text: JSON.stringify(salida, null, 2),
18
28
  }],
19
29
  };
20
30
  });
@@ -1 +1 @@
1
- {"version":3,"file":"estadisticas-uso.js","sourceRoot":"","sources":["../../src/tools/estadisticas-uso.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAC7C,MAAM,gBAAgB,GAAG,yKAAyK,CAAC;AAEnM,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAwB;IACjF,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,WAAW,EAAE,gBAAgB;KAC9B,EACD,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACzC,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrC,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"estadisticas-uso.js","sourceRoot":"","sources":["../../src/tools/estadisticas-uso.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAC7C,MAAM,gBAAgB,GAAG;gQACuO,CAAC;AAEjQ,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAwB;IACjF,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,WAAW,EAAE,gBAAgB;KAC9B,EACD,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG;YACb,QAAQ,EAAE,6LAA6L;YACvM,mBAAmB,EAAE,KAAK,CAAC,aAAa;YACxC,aAAa,EAAE,KAAK,CAAC,SAAS;YAC9B,cAAc,EAAE,KAAK,CAAC,SAAS;YAC/B,KAAK,EAAE,KAAK,CAAC,SAAS;gBACpB,CAAC,CAAC,4HAA4H;gBAC9H,CAAC,CAAC,4IAA4I;SACjJ,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,28 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { CompraAgilClient } from '../api/compra-agil-client.js';
2
+ import { CompraAgilClient, CompraAgilDetalle } from '../api/compra-agil-client.js';
3
+ /** Precio de relleno cuando no se pudo estimar nada. Hay que advertirlo. */
4
+ export declare const PRECIO_PLACEHOLDER = 1000;
5
+ export interface EstimacionPrecio {
6
+ precio: number;
7
+ fuente: string;
8
+ /** `false` ⇒ es el placeholder y el borrador debe advertirlo. */
9
+ sugerido: boolean;
10
+ }
11
+ /**
12
+ * Decide el precio unitario del borrador, en orden de preferencia:
13
+ * 1. el que ingresó el usuario,
14
+ * 2. el percentil 25 de lo que cotizó el mercado en procesos similares,
15
+ * 3. el presupuesto del comprador menos 10%,
16
+ * 4. un placeholder de $1.000, que se advierte explícitamente.
17
+ *
18
+ * ⚠ POR QUÉ EL PASO 3 VIVE FUERA DEL try: antes, la consulta de precios de
19
+ * mercado y el respaldo por presupuesto estaban dentro del mismo bloque, así
20
+ * que CUALQUIER fallo de la API durante la consulta —un 429 por cuota
21
+ * agotada, típicamente— saltaba también el respaldo y el borrador salía con
22
+ * $1.000, pese a que el presupuesto ya estaba en la mano desde el detalle y
23
+ * no requería ninguna llamada adicional. Detectado en auditoría: un llamado
24
+ * de $4.800.000 generó un borrador de $1.000 por este camino.
25
+ */
26
+ export declare function estimarPrecioUnitario(client: Pick<CompraAgilClient, 'buscar' | 'detalle'>, detalle: CompraAgilDetalle, precioPersonalizado?: number): Promise<EstimacionPrecio>;
3
27
  export declare function registerGenerarBorrador(server: McpServer, client: CompraAgilClient): void;
4
28
  //# sourceMappingURL=generar-borrador.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generar-borrador.d.ts","sourceRoot":"","sources":["../../src/tools/generar-borrador.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAkBhE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiLzF"}
1
+ {"version":3,"file":"generar-borrador.d.ts","sourceRoot":"","sources":["../../src/tools/generar-borrador.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAMnF,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,SAAS,CAAC,EACpD,OAAO,EAAE,iBAAiB,EAC1B,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAwE3B;AAgBD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA+GzF"}
@@ -1,6 +1,100 @@
1
1
  import { z } from 'zod';
2
2
  import { CompraAgilApiError } from '../utils/error-handler.js';
3
3
  import { logger } from '../utils/logger.js';
4
+ import { extraerPrecioUnitario, percentil } from '../utils/quotation.js';
5
+ import { safeError } from '../utils/redact.js';
6
+ /** Precio de relleno cuando no se pudo estimar nada. Hay que advertirlo. */
7
+ export const PRECIO_PLACEHOLDER = 1000;
8
+ /** Presupuesto del comprador, mirando también el estimado. */
9
+ function presupuestoDelComprador(detalle) {
10
+ const p = detalle.presupuesto;
11
+ return p?.monto_disponible_clp || p?.monto_disponible || p?.presupuesto_estimado || 0;
12
+ }
13
+ /**
14
+ * Decide el precio unitario del borrador, en orden de preferencia:
15
+ * 1. el que ingresó el usuario,
16
+ * 2. el percentil 25 de lo que cotizó el mercado en procesos similares,
17
+ * 3. el presupuesto del comprador menos 10%,
18
+ * 4. un placeholder de $1.000, que se advierte explícitamente.
19
+ *
20
+ * ⚠ POR QUÉ EL PASO 3 VIVE FUERA DEL try: antes, la consulta de precios de
21
+ * mercado y el respaldo por presupuesto estaban dentro del mismo bloque, así
22
+ * que CUALQUIER fallo de la API durante la consulta —un 429 por cuota
23
+ * agotada, típicamente— saltaba también el respaldo y el borrador salía con
24
+ * $1.000, pese a que el presupuesto ya estaba en la mano desde el detalle y
25
+ * no requería ninguna llamada adicional. Detectado en auditoría: un llamado
26
+ * de $4.800.000 generó un borrador de $1.000 por este camino.
27
+ */
28
+ export async function estimarPrecioUnitario(client, detalle, precioPersonalizado) {
29
+ if (precioPersonalizado !== undefined && precioPersonalizado > 0) {
30
+ return {
31
+ precio: precioPersonalizado,
32
+ fuente: 'Precio neto ingresado por el usuario',
33
+ sugerido: true,
34
+ };
35
+ }
36
+ const keyword = detalle.productos_solicitados?.[0]?.nombre || detalle.nombre || '';
37
+ const precios = [];
38
+ if (keyword) {
39
+ try {
40
+ logger.info(`generar_borrador_cotizacion: Consultando precios cotizados por el mercado para "${keyword}"`);
41
+ // Solo `desierta`: medido contra la API real, es el único estado que
42
+ // publica cotizaciones (desierta 5/8 procesos con precios; cerrada 0/8).
43
+ // `proveedor_seleccionado` devuelve 0 resultados.
44
+ const busqueda = await client.buscar({
45
+ q: keyword,
46
+ estado: 'desierta',
47
+ tamano_pagina: 50,
48
+ numero_pagina: 1,
49
+ });
50
+ for (const item of (busqueda.items || []).slice(0, 5)) {
51
+ try {
52
+ const det = await client.detalle(item.codigo);
53
+ // Se toman TODAS las cotizaciones, incluidas las inadmisibles: en los
54
+ // procesos desiertos casi todas lo son (por eso quedaron desiertos), y
55
+ // el precio ofertado sigue siendo señal de mercado. Filtrarlas dejaba
56
+ // la muestra vacía. La API nunca marca un ganador, así que la
57
+ // referencia es lo que ofertó la competencia.
58
+ for (const prov of det.proveedores_cotizando ?? []) {
59
+ const unitario = extraerPrecioUnitario(prov, keyword);
60
+ if (unitario !== null)
61
+ precios.push(unitario);
62
+ }
63
+ }
64
+ catch {
65
+ // Un histórico que falla no invalida el resto de la muestra.
66
+ }
67
+ }
68
+ }
69
+ catch (err) {
70
+ logger.warn(`generar_borrador_cotizacion: No se pudo consultar precios de mercado: ${safeError(err)}`);
71
+ }
72
+ }
73
+ if (precios.length > 0) {
74
+ precios.sort((a, b) => a - b);
75
+ // Percentil 25 de lo cotizado: ubica la oferta en el cuarto más económico
76
+ // sin regalar margen, y resiste valores atípicos mejor que un promedio.
77
+ return {
78
+ precio: percentil(precios, 25),
79
+ fuente: `Sugerencia automática: percentil 25 de ${precios.length} precio(s) cotizado(s) por el mercado en procesos similares (NO son precios adjudicados: la API no los expone)`,
80
+ sugerido: true,
81
+ };
82
+ }
83
+ const presupuesto = presupuestoDelComprador(detalle);
84
+ if (presupuesto > 0) {
85
+ const cantidadTotal = detalle.productos_solicitados?.reduce((acc, p) => acc + p.cantidad, 0) || 1;
86
+ return {
87
+ precio: Math.round((presupuesto * 0.9) / cantidadTotal),
88
+ fuente: 'Sugerencia automática: presupuesto del comprador descontado 10% (no hubo cotizaciones de mercado comparables)',
89
+ sugerido: true,
90
+ };
91
+ }
92
+ return {
93
+ precio: PRECIO_PLACEHOLDER,
94
+ fuente: `Valor por defecto (placeholder de $${PRECIO_PLACEHOLDER.toLocaleString('es-CL')})`,
95
+ sugerido: false,
96
+ };
97
+ }
4
98
  const TOOL_NAME = 'generar_borrador_cotizacion';
5
99
  const TOOL_DESCRIPTION = `Genera un borrador estructurado en formato JSON para presentar una cotización formal a un llamado de Compra Ágil activa.
6
100
  Calcula automáticamente los valores netos, impuestos (19% IVA de Chile) y montos brutos, sugiriendo un precio unitario de mercado si no se ingresa uno personalizado.`;
@@ -20,92 +114,22 @@ export function registerGenerarBorrador(server, client) {
20
114
  try {
21
115
  logger.info(`generar_borrador_cotizacion: Obteniendo detalle de la compra activa ${args.codigo_compra}`);
22
116
  const targetDetail = await client.detalle(args.codigo_compra);
117
+ // Detectar qué campos son placeholders (no aportados por el usuario) para advertir en la salida.
118
+ const advertencias = [];
23
119
  const rutProv = args.rut_proveedor || '76.000.000-0';
24
120
  const razonSocial = args.razon_social || 'Proveedor Demo SpA';
25
- const customPrice = args.precio_unitario_personalizado;
121
+ if (!args.rut_proveedor)
122
+ advertencias.push('rut_proveedor es un valor PLACEHOLDER; reemplázalo por el RUT real del proveedor antes de presentar.');
123
+ if (!args.razon_social)
124
+ advertencias.push('razon_social es un valor PLACEHOLDER; reemplázalo por la razón social real.');
26
125
  let plazoEntrega = args.plazo_entrega_dias;
27
126
  if (plazoEntrega === undefined) {
28
127
  plazoEntrega = targetDetail.entrega?.plazo_entrega_dias || 5;
29
128
  }
30
- // Estimar o adoptar precio unitario
31
- let suggestedPrice = 1000;
32
- let isPriceSuggested = false;
33
- let priceSource = 'Valor por defecto (placeholder de $1.000)';
34
- if (customPrice !== undefined && customPrice > 0) {
35
- suggestedPrice = customPrice;
36
- priceSource = 'Precio neto ingresado por el usuario';
37
- isPriceSuggested = true;
38
- }
39
- else {
40
- // Intentar obtener palabras clave del primer producto solicitado
41
- let keyword = '';
42
- if (targetDetail.productos_solicitados && targetDetail.productos_solicitados.length > 0) {
43
- keyword = targetDetail.productos_solicitados[0].nombre;
44
- }
45
- else {
46
- keyword = targetDetail.nombre;
47
- }
48
- if (keyword) {
49
- try {
50
- logger.info(`generar_borrador_cotizacion: Consultando precios de referencia históricos para "${keyword}"`);
51
- const searchResponse = await client.buscar({
52
- q: keyword,
53
- estado: 'proveedor_seleccionado',
54
- tamano_pagina: 10, // API v2 requiere mínimo 10
55
- numero_pagina: 1,
56
- });
57
- const prices = [];
58
- const itemsToProcess = (searchResponse.items || []).slice(0, 3);
59
- if (itemsToProcess.length > 0) {
60
- for (const item of itemsToProcess) {
61
- try {
62
- const detail = await client.detalle(item.codigo);
63
- const winner = detail.proveedores_cotizando?.find(prov => prov.proveedor_seleccionado === true ||
64
- prov.proveedor_seleccionado === 1 ||
65
- (prov.seleccion && prov.seleccion.proveedor_seleccionado === true));
66
- if (winner) {
67
- let unitPrice = null;
68
- if (winner.productos_cotizados && winner.productos_cotizados.length > 0) {
69
- const matched = winner.productos_cotizados.find(p => p.nombre_producto.toLowerCase().includes(keyword.toLowerCase()));
70
- unitPrice = matched ? matched.precio_unitario : winner.productos_cotizados[0].precio_unitario;
71
- }
72
- const val = unitPrice || winner.valor_neto || winner.monto_total || 0;
73
- if (val > 0)
74
- prices.push(val);
75
- }
76
- }
77
- catch (e) {
78
- // ignore errors for individual historical lookups
79
- }
80
- }
81
- }
82
- if (prices.length > 0) {
83
- prices.sort((a, b) => a - b);
84
- const avg = Math.round(prices.reduce((a, b) => a + b, 0) / prices.length);
85
- // Sugerir un precio competitivo (5% menor al promedio adjudicado)
86
- suggestedPrice = Math.round(avg * 0.95);
87
- if (suggestedPrice < prices[0]) {
88
- suggestedPrice = prices[0];
89
- }
90
- priceSource = 'Sugerencia automática: Percentil de mercado (5% bajo promedio histórico)';
91
- isPriceSuggested = true;
92
- }
93
- else {
94
- // Fallback: usar presupuesto estimado del comprador si existe
95
- const totalCantidad = targetDetail.productos_solicitados?.reduce((acc, p) => acc + p.cantidad, 0) || 1;
96
- const budget = targetDetail.presupuesto?.monto_disponible_clp || targetDetail.presupuesto?.monto_disponible || 0;
97
- if (budget > 0) {
98
- suggestedPrice = Math.round((budget * 0.9) / totalCantidad);
99
- priceSource = 'Sugerencia automática: Presupuesto estimado del comprador (descontado 10%)';
100
- isPriceSuggested = true;
101
- }
102
- }
103
- }
104
- catch (err) {
105
- logger.warn(`generar_borrador_cotizacion: No se pudo estimar precio sugerido: ${String(err)}`);
106
- }
107
- }
108
- }
129
+ const estimacion = await estimarPrecioUnitario(client, targetDetail, args.precio_unitario_personalizado);
130
+ const suggestedPrice = estimacion.precio;
131
+ const isPriceSuggested = estimacion.sugerido;
132
+ const priceSource = estimacion.fuente;
109
133
  // Construir productos cotizados
110
134
  const productosCotizados = (targetDetail.productos_solicitados || []).map(prod => {
111
135
  const uPrice = suggestedPrice;
@@ -135,13 +159,18 @@ export function registerGenerarBorrador(server, client) {
135
159
  `Agradecemos de antemano su consideración y nos mantenemos a su disposición para aclarar cualquier duda técnica o comercial.\n\n` +
136
160
  `Atentamente,\n` +
137
161
  `${razonSocial}\nRUT: ${rutProv}`;
162
+ if (!isPriceSuggested) {
163
+ advertencias.push(`precio_unitario es un valor por defecto ($${suggestedPrice.toLocaleString('es-CL')}); no se pudo estimar de mercado. Ingresa "precio_unitario_personalizado".`);
164
+ }
138
165
  const borradorCotizacion = {
166
+ _advertencia: '⚠ BORRADOR AUTOGENERADO. Revisa y reemplaza los campos marcados como placeholder antes de presentar la cotización real. Este documento no ha sido enviado a Mercado Público.',
167
+ _campos_a_revisar: advertencias,
139
168
  codigo_compra: targetDetail.codigo,
140
169
  nombre_compra: targetDetail.nombre,
141
170
  organismo_comprador: targetDetail.institucion?.organismo_comprador || 'No especificado',
142
171
  rut_proveedor: rutProv,
143
172
  razon_social: razonSocial,
144
- es_emt: true,
173
+ es_emt: null, // Desconocido: depende del Registro de Proveedores del RUT real, no se asume.
145
174
  activo: true,
146
175
  plazo_entrega_dias: plazoEntrega,
147
176
  valor_neto: valorNeto,
@@ -167,7 +196,7 @@ export function registerGenerarBorrador(server, client) {
167
196
  catch (error) {
168
197
  const message = error instanceof CompraAgilApiError
169
198
  ? error.actionableMessage
170
- : `Error inesperado al generar borrador de cotización: ${String(error)}`;
199
+ : `Error inesperado al generar borrador de cotización: ${safeError(error)}`;
171
200
  return {
172
201
  content: [{ type: 'text', text: message }],
173
202
  isError: true,