@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
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Redacción de secretos: punto único de estrangulamiento.
3
+ *
4
+ * POR QUÉ EXISTE
5
+ * El ticket de acceso viaja en la query string del endpoint legado
6
+ * (/servicios/.../OrdenCompra.json). Se verificó empíricamente que algunos
7
+ * errores de `fetch` incluyen la URL completa en su mensaje:
8
+ *
9
+ * TypeError: Failed to parse URL from http://host/x?ticket=SECRETO
10
+ *
11
+ * Ese texto termina en la respuesta de la tool → contexto del LLM →
12
+ * transcripción, logs y capturas de pantalla. Auditar caso por caso cada
13
+ * `String(error)` es una batalla perdida: siempre aparecerá una ruta nueva.
14
+ *
15
+ * En vez de eso, TODO string que sale del proceso pasa por `redact()`.
16
+ * Aunque surja un camino de error imprevisto, el secreto no se escapa.
17
+ *
18
+ * Se aplica en tres puntos: el logger, el error-handler y los catch de tools.
19
+ */
20
+ const MARCA = '[REDACTED]';
21
+ /** Longitud mínima para registrar un secreto: evita redactar palabras comunes. */
22
+ const LARGO_MINIMO = 8;
23
+ const secretos = new Set();
24
+ /**
25
+ * Registra un valor secreto para que sea removido de toda salida.
26
+ * Idempotente y seguro de llamar con undefined.
27
+ */
28
+ export function registrarSecreto(valor) {
29
+ if (!valor)
30
+ return;
31
+ const v = valor.trim();
32
+ // Un secreto muy corto redactaría texto legítimo por coincidencia.
33
+ if (v.length < LARGO_MINIMO)
34
+ return;
35
+ secretos.add(v);
36
+ // La misma credencial puede aparecer URL-encodeada dentro de una URL.
37
+ const encoded = encodeURIComponent(v);
38
+ if (encoded !== v)
39
+ secretos.add(encoded);
40
+ }
41
+ /** Solo para tests: limpia los secretos registrados. */
42
+ export function _resetSecretos() {
43
+ secretos.clear();
44
+ }
45
+ /** Cantidad de secretos registrados (diagnóstico). */
46
+ export function secretosRegistrados() {
47
+ return secretos.size;
48
+ }
49
+ /**
50
+ * Elimina cualquier secreto conocido de un texto.
51
+ *
52
+ * Defensa en dos capas:
53
+ * 1. Coincidencia exacta de los secretos registrados.
54
+ * 2. Patrón `ticket=<valor>` en query strings — cubre el caso en que el
55
+ * secreto no alcanzó a registrarse (ej. error durante el arranque).
56
+ */
57
+ export function redact(texto) {
58
+ if (!texto)
59
+ return texto;
60
+ let out = texto;
61
+ for (const s of secretos) {
62
+ if (out.includes(s)) {
63
+ out = out.split(s).join(MARCA);
64
+ }
65
+ }
66
+ // Capa 2: cualquier ticket= en una URL, esté o no registrado.
67
+ out = out.replace(/([?&]ticket=)[^&\s"'<>)\]]+/gi, `$1${MARCA}`);
68
+ // Capa 2b: header/JSON con forma "ticket": "valor"
69
+ out = out.replace(/(["']?ticket["']?\s*[:=]\s*["'])([^"']+)(["'])/gi, `$1${MARCA}$3`);
70
+ return out;
71
+ }
72
+ /**
73
+ * Convierte cualquier valor lanzado en un string seguro para mostrar.
74
+ * Reemplaza el patrón `String(error)` usado en los catch de las tools.
75
+ */
76
+ export function safeError(error) {
77
+ let base;
78
+ if (error instanceof Error) {
79
+ // El `cause` de undici puede traer detalle útil (y potencialmente la URL).
80
+ const cause = error.cause;
81
+ base = cause ? `${error.message} (${String(cause)})` : error.message;
82
+ }
83
+ else {
84
+ base = String(error);
85
+ }
86
+ return redact(base);
87
+ }
88
+ /**
89
+ * Enmascara una credencial para mostrarla como referencia sin revelarla.
90
+ * Ej: "abcd1234-ef56-7890" → "••••7890"
91
+ */
92
+ export function pista(valor) {
93
+ if (!valor)
94
+ return '(no configurado)';
95
+ const v = valor.trim();
96
+ if (v.length <= 4)
97
+ return '••••';
98
+ return `••••${v.slice(-4)}`;
99
+ }
100
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/utils/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,KAAK,GAAG,YAAY,CAAC;AAE3B,kFAAkF;AAClF,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAgC;IAC/D,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,mEAAmE;IACnE,IAAI,CAAC,CAAC,MAAM,GAAG,YAAY;QAAE,OAAO;IAEpC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEhB,sEAAsE;IACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,OAAO,KAAK,CAAC;QAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,cAAc;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,mBAAmB;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,GAAG,GAAG,KAAK,CAAC;IAEhB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC;IACjE,mDAAmD;IACnD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,kDAAkD,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC;IAEtF,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,IAAY,CAAC;IACjB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,2EAA2E;QAC3E,MAAM,KAAK,GAAI,KAAqC,CAAC,KAAK,CAAC;QAC3D,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,KAAgC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,kBAAkB,CAAC;IACtC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9B,CAAC"}
package/package.json CHANGED
@@ -1,53 +1,55 @@
1
- {
2
- "name": "@ssolis-ti/mcp-compra-agil",
3
- "version": "1.0.3",
4
- "description": "Servidor MCP para la API Compra Ágil v2 de Mercado Público (Chile)",
5
- "type": "module",
6
- "bin": {
7
- "mcp-compra-agil": "dist/index.js"
8
- },
9
- "files": [
10
- "dist"
11
- ],
12
- "author": "ssolis-ti",
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/ssolis-ti/compra-agil-mcp.git"
16
- },
17
- "bugs": {
18
- "url": "https://github.com/ssolis-ti/compra-agil-mcp/issues"
19
- },
20
- "homepage": "https://github.com/ssolis-ti/compra-agil-mcp#readme",
21
- "scripts": {
22
- "build": "tsc",
23
- "start": "node dist/index.js",
24
- "dev": "tsx watch src/index.ts",
25
- "inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
26
- "monitor": "node dist/services/monitor.js",
27
- "prepublishOnly": "npm run build"
28
- },
29
- "dependencies": {
30
- "@modelcontextprotocol/sdk": "^1.12.0",
31
- "pdf-parse": "^2.4.5",
32
- "zod": "^3.24.0"
33
- },
34
- "devDependencies": {
35
- "@types/node": "^22.0.0",
36
- "@types/pdf-parse": "^1.1.5",
37
- "tsx": "^4.19.0",
38
- "typescript": "^5.7.0"
39
- },
40
- "keywords": [
41
- "mcp",
42
- "model-context-protocol",
43
- "compra-agil",
44
- "mercado-publico",
45
- "chile",
46
- "gobierno",
47
- "licitaciones"
48
- ],
49
- "license": "MIT",
50
- "publishConfig": {
51
- "access": "public"
52
- }
53
- }
1
+ {
2
+ "name": "@ssolis-ti/mcp-compra-agil",
3
+ "version": "2.3.0",
4
+ "description": "Servidor MCP para la API Compra Ágil v2 de Mercado Público (Chile)",
5
+ "type": "module",
6
+ "bin": {
7
+ "mcp-compra-agil": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "author": "ssolis-ti",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/ssolis-ti/compra-agil-mcp.git"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/ssolis-ti/compra-agil-mcp/issues"
19
+ },
20
+ "homepage": "https://github.com/ssolis-ti/compra-agil-mcp#readme",
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "start": "node dist/index.js",
24
+ "dev": "tsx watch src/index.ts",
25
+ "inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
26
+ "monitor": "node dist/services/monitor.js",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "prepublishOnly": "npm run build && npm test"
30
+ },
31
+ "dependencies": {
32
+ "@modelcontextprotocol/sdk": "^1.12.0",
33
+ "pdf-parse": "^2.4.5",
34
+ "zod": "^3.24.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.0.0",
38
+ "tsx": "^4.19.0",
39
+ "typescript": "^5.7.0",
40
+ "vitest": "^3.2.7"
41
+ },
42
+ "keywords": [
43
+ "mcp",
44
+ "model-context-protocol",
45
+ "compra-agil",
46
+ "mercado-publico",
47
+ "chile",
48
+ "gobierno",
49
+ "licitaciones"
50
+ ],
51
+ "license": "MIT",
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }