siag-mcp 2.0.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.
- package/README.md +91 -0
- package/index.js +317 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# SIAG MCP Client
|
|
2
|
+
|
|
3
|
+
Cliente MCP para **Claude Desktop** que conecta con el servidor centralizado SIAG en n8n.
|
|
4
|
+
Soporta múltiples empresas en una sola instalación.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
Claude Desktop ──stdio──▶ siag-mcp-client ──HTTPS POST──▶ n8n webhook ──▶ SIAG API
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Instalación rápida (Windows — usuarios no técnicos)
|
|
13
|
+
|
|
14
|
+
1. Asegúrate de tener [Node.js 18+](https://nodejs.org) instalado
|
|
15
|
+
2. Abre **PowerShell** y ejecuta:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
19
|
+
irm https://gitlab.com/sgsst/siag-mcp-client/-/raw/main/install.ps1 | iex
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. El instalador te pedirá el nombre y API Key de cada empresa
|
|
23
|
+
4. Reinicia Claude Desktop
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Configuración manual
|
|
28
|
+
|
|
29
|
+
Edita `%APPDATA%\Claude\claude_desktop_config.json`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"siag": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["-y", "@sgsst/siag-mcp"],
|
|
37
|
+
"env": {
|
|
38
|
+
"SIAG_API_KEY_EMPRESA1": "API-tu-key-empresa1",
|
|
39
|
+
"SIAG_API_KEY_EMPRESA2": "API-tu-key-empresa2"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Reinicia Claude Desktop.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Variables de entorno
|
|
51
|
+
|
|
52
|
+
| Variable | Empresa detectada | Ejemplo |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `SIAG_API_KEY` | `default` (legacy) | `SIAG_API_KEY=API-xxx` |
|
|
55
|
+
| `SIAG_API_KEY_<NOMBRE>` | El nombre en minúsculas | `SIAG_API_KEY_ACME=API-yyy` → empresa `acme` |
|
|
56
|
+
|
|
57
|
+
Puedes configurar una o varias empresas. Si hay más de una, Claude pedirá
|
|
58
|
+
el parámetro `empresa` en cada consulta.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Herramientas disponibles
|
|
63
|
+
|
|
64
|
+
| Herramienta | Descripción | Parámetro `empresa` |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `listar_empresas` | Lista las empresas configuradas | No aplica |
|
|
67
|
+
| `listar_incapacidades` | Lista con filtros opcionales | Requerido si hay varias |
|
|
68
|
+
| `obtener_incapacidad` | Detalle por ID | Requerido si hay varias |
|
|
69
|
+
| `listar_ausentismo` | Lista con filtros opcionales | Requerido si hay varias |
|
|
70
|
+
| `obtener_ausentismo` | Detalle por ID | Requerido si hay varias |
|
|
71
|
+
| `verificar_conexion` | Diagnóstico de conectividad | Requerido si hay varias |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Ejemplos de uso en Claude
|
|
76
|
+
|
|
77
|
+
- *"¿Qué empresas tengo configuradas?"*
|
|
78
|
+
- *"Lista las incapacidades de la empresa acme del empleado 12345678 en 2025"*
|
|
79
|
+
- *"¿Cuántos días de ausentismo tuvo el área de producción en constructora este mes?"*
|
|
80
|
+
- *"Muéstrame el detalle de la incapacidad con ID 450 en empresa1"*
|
|
81
|
+
- *"Verifica si SIAG está respondiendo para acme"*
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Publicación
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm publish --access public
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> Requiere cuenta en npm y haber hecho `npm login` previamente.
|
package/index.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SIAG MCP Client
|
|
5
|
+
* ───────────────
|
|
6
|
+
* Cliente MCP para Claude Desktop que se comunica con el
|
|
7
|
+
* MCP Server centralizado en n8n (webhook /siag-mcp).
|
|
8
|
+
*
|
|
9
|
+
* Configuración en variables de entorno (o .env):
|
|
10
|
+
* SIAG_API_KEY → API key legacy (empresa "default")
|
|
11
|
+
* SIAG_API_KEY_<EMPRESA> → API key por empresa (ej: SIAG_API_KEY_ACME)
|
|
12
|
+
* N8N_WEBHOOK_URL → URL del webhook n8n (opcional)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require("fs");
|
|
16
|
+
const path = require("path");
|
|
17
|
+
const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
18
|
+
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
19
|
+
const { z } = require("zod");
|
|
20
|
+
const axios = require("axios");
|
|
21
|
+
|
|
22
|
+
// Cargar variables de entorno manualmente desde .env sin usar console
|
|
23
|
+
const envPath = path.join(__dirname, ".env");
|
|
24
|
+
if (fs.existsSync(envPath)) {
|
|
25
|
+
const envContent = fs.readFileSync(envPath, "utf-8");
|
|
26
|
+
envContent.split("\n").forEach((line) => {
|
|
27
|
+
const trimmed = line.trim();
|
|
28
|
+
if (trimmed && !trimmed.startsWith("#")) {
|
|
29
|
+
const [key, ...valueParts] = trimmed.split("=");
|
|
30
|
+
if (key) process.env[key.trim()] = valueParts.join("=").trim();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ─── Configuración multi-empresa ──────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
const WEBHOOK_URL = process.env.N8N_WEBHOOK_URL || "https://automate.sgsst.co/webhook/siag-mcp";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Construye el mapa de empresas desde variables de entorno.
|
|
41
|
+
* Soporta:
|
|
42
|
+
* SIAG_API_KEY → empresa "default" (compatibilidad legacy)
|
|
43
|
+
* SIAG_API_KEY_<EMPRESA> → empresa con nombre (ej: SIAG_API_KEY_ACME → "acme")
|
|
44
|
+
*/
|
|
45
|
+
function buildCompanyMap() {
|
|
46
|
+
const map = {};
|
|
47
|
+
const PREFIX = "SIAG_API_KEY_";
|
|
48
|
+
|
|
49
|
+
// Legacy: clave sin sufijo
|
|
50
|
+
if (process.env.SIAG_API_KEY) {
|
|
51
|
+
map["default"] = process.env.SIAG_API_KEY;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Prefijadas: SIAG_API_KEY_<EMPRESA>
|
|
55
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
56
|
+
if (key.startsWith(PREFIX) && value) {
|
|
57
|
+
const empresa = key.slice(PREFIX.length).toLowerCase();
|
|
58
|
+
map[empresa] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return map;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const COMPANIES = buildCompanyMap();
|
|
66
|
+
const COMPANY_NAMES = Object.keys(COMPANIES);
|
|
67
|
+
const IS_MULTI = COMPANY_NAMES.length > 1;
|
|
68
|
+
|
|
69
|
+
if (COMPANY_NAMES.length === 0) {
|
|
70
|
+
console.error(
|
|
71
|
+
"❌ ERROR: No se encontró ninguna API key de SIAG.\n" +
|
|
72
|
+
" Configura SIAG_API_KEY o SIAG_API_KEY_<EMPRESA>=... en el entorno."
|
|
73
|
+
);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Resuelve la API key para la empresa indicada.
|
|
79
|
+
* - Si hay 1 sola empresa: el parámetro empresa es ignorado.
|
|
80
|
+
* - Si hay varias: empresa es obligatorio y debe coincidir.
|
|
81
|
+
*/
|
|
82
|
+
function resolveApiKey(empresa) {
|
|
83
|
+
if (!IS_MULTI) {
|
|
84
|
+
return { apiKey: COMPANIES[COMPANY_NAMES[0]], resolvedName: COMPANY_NAMES[0] };
|
|
85
|
+
}
|
|
86
|
+
if (!empresa) {
|
|
87
|
+
return {
|
|
88
|
+
error:
|
|
89
|
+
`Se configuraron varias empresas (${COMPANY_NAMES.join(", ")}). ` +
|
|
90
|
+
"Debes indicar el parámetro 'empresa'. Usa listar_empresas para ver las disponibles."
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const normalized = empresa.toLowerCase();
|
|
94
|
+
const apiKey = COMPANIES[normalized];
|
|
95
|
+
if (!apiKey) {
|
|
96
|
+
return {
|
|
97
|
+
error: `Empresa '${empresa}' no encontrada. Disponibles: ${COMPANY_NAMES.join(", ")}`
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return { apiKey, resolvedName: normalized };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ─── Llamada al MCP Server (n8n) ──────────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
async function callServer(apiKey, tool, params = {}) {
|
|
106
|
+
const { data } = await axios.post(
|
|
107
|
+
WEBHOOK_URL,
|
|
108
|
+
{ api_key: apiKey, tool, params },
|
|
109
|
+
{ headers: { "Content-Type": "application/json" }, timeout: 30000 }
|
|
110
|
+
);
|
|
111
|
+
return data;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function ok(text) {
|
|
115
|
+
return { content: [{ type: "text", text: typeof text === "string" ? text : JSON.stringify(text, null, 2) }] };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function err(msg) {
|
|
119
|
+
return { content: [{ type: "text", text: `❌ ${msg}` }], isError: true };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── Servidor MCP ─────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
const server = new McpServer(
|
|
125
|
+
{ name: "siag-client", version: "2.0.0" },
|
|
126
|
+
{
|
|
127
|
+
capabilities: { tools: {} },
|
|
128
|
+
instructions: [
|
|
129
|
+
"Cliente MCP de SIAG (SGSST) — solo lectura.",
|
|
130
|
+
"Consulta incapacidades laborales y ausentismo de personas.",
|
|
131
|
+
IS_MULTI
|
|
132
|
+
? `Empresas configuradas: ${COMPANY_NAMES.join(", ")}. Usa el parámetro 'empresa' en cada llamada.`
|
|
133
|
+
: `Empresa activa: ${COMPANY_NAMES[0]}.`,
|
|
134
|
+
"Las llamadas se enrutan al servidor centralizado en n8n.",
|
|
135
|
+
].join(" "),
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// ─── Helper Zod reutilizable para el campo empresa ────────────────────────────
|
|
140
|
+
|
|
141
|
+
const empresaField = IS_MULTI
|
|
142
|
+
? z.string().describe(
|
|
143
|
+
`Nombre de la empresa a consultar. Opciones: ${COMPANY_NAMES.join(", ")}`
|
|
144
|
+
)
|
|
145
|
+
: z.string().optional().describe(
|
|
146
|
+
`Empresa (opcional — única configurada: ${COMPANY_NAMES[0]})`
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
150
|
+
// EMPRESAS
|
|
151
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
152
|
+
|
|
153
|
+
server.tool(
|
|
154
|
+
"listar_empresas",
|
|
155
|
+
"Lista las empresas configuradas en este cliente SIAG MCP.",
|
|
156
|
+
{},
|
|
157
|
+
async () => {
|
|
158
|
+
const PREFIX = "SIAG_API_KEY_";
|
|
159
|
+
const list = COMPANY_NAMES.map((name) => ({
|
|
160
|
+
empresa: name,
|
|
161
|
+
variable: name === "default" ? "SIAG_API_KEY" : `${PREFIX}${name.toUpperCase()}`,
|
|
162
|
+
}));
|
|
163
|
+
return ok({ empresas: list, total: list.length });
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
168
|
+
// INCAPACIDAD LABORAL
|
|
169
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
170
|
+
|
|
171
|
+
server.tool(
|
|
172
|
+
"listar_incapacidades",
|
|
173
|
+
"Lista las incapacidades laborales registradas en SIAG. Todos los filtros son opcionales.",
|
|
174
|
+
{
|
|
175
|
+
empresa: empresaField,
|
|
176
|
+
documento_empleado: z.string().optional()
|
|
177
|
+
.describe("Número de documento del empleado"),
|
|
178
|
+
fecha_inicio: z.string().optional()
|
|
179
|
+
.describe("Fecha inicio del rango a consultar (YYYY-MM-DD)"),
|
|
180
|
+
fecha_fin: z.string().optional()
|
|
181
|
+
.describe("Fecha fin del rango a consultar (YYYY-MM-DD)"),
|
|
182
|
+
tipo_incapacidad: z.string().optional()
|
|
183
|
+
.describe("Tipo: enfermedad_general, accidente_trabajo, enfermedad_laboral, maternidad, paternidad"),
|
|
184
|
+
estado: z.string().optional()
|
|
185
|
+
.describe("Estado: activa, cerrada, pendiente"),
|
|
186
|
+
pagina: z.number().int().positive().optional()
|
|
187
|
+
.describe("Número de página (default: 1)"),
|
|
188
|
+
limite: z.number().int().positive().max(100).optional()
|
|
189
|
+
.describe("Registros por página (default: 20, máx: 100)"),
|
|
190
|
+
},
|
|
191
|
+
async ({ empresa, ...rest }) => {
|
|
192
|
+
const resolved = resolveApiKey(empresa);
|
|
193
|
+
if (resolved.error) return err(resolved.error);
|
|
194
|
+
try {
|
|
195
|
+
const result = await callServer(resolved.apiKey, "listar_incapacidades", rest);
|
|
196
|
+
return ok(result);
|
|
197
|
+
} catch (e) {
|
|
198
|
+
return err(`listar_incapacidades: ${e.message}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
server.tool(
|
|
204
|
+
"obtener_incapacidad",
|
|
205
|
+
"Obtiene el detalle completo de una incapacidad laboral por su ID.",
|
|
206
|
+
{
|
|
207
|
+
empresa: empresaField,
|
|
208
|
+
id: z.string().describe("ID único de la incapacidad laboral"),
|
|
209
|
+
},
|
|
210
|
+
async ({ empresa, id }) => {
|
|
211
|
+
const resolved = resolveApiKey(empresa);
|
|
212
|
+
if (resolved.error) return err(resolved.error);
|
|
213
|
+
try {
|
|
214
|
+
const result = await callServer(resolved.apiKey, "obtener_incapacidad", { id });
|
|
215
|
+
return ok(result);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
return err(`obtener_incapacidad [${id}]: ${e.message}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
223
|
+
// AUSENTISMO PERSONA
|
|
224
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
225
|
+
|
|
226
|
+
server.tool(
|
|
227
|
+
"listar_ausentismo",
|
|
228
|
+
"Lista los registros de ausentismo de personas en SIAG. Todos los filtros son opcionales.",
|
|
229
|
+
{
|
|
230
|
+
empresa: empresaField,
|
|
231
|
+
documento_empleado: z.string().optional()
|
|
232
|
+
.describe("Número de documento del empleado"),
|
|
233
|
+
fecha_inicio: z.string().optional()
|
|
234
|
+
.describe("Fecha inicio del período (YYYY-MM-DD)"),
|
|
235
|
+
fecha_fin: z.string().optional()
|
|
236
|
+
.describe("Fecha fin del período (YYYY-MM-DD)"),
|
|
237
|
+
tipo_ausentismo: z.string().optional()
|
|
238
|
+
.describe("Tipo: incapacidad, calamidad, vacaciones, licencia, otro"),
|
|
239
|
+
area: z.string().optional()
|
|
240
|
+
.describe("Área o departamento"),
|
|
241
|
+
cargo: z.string().optional()
|
|
242
|
+
.describe("Cargo del empleado"),
|
|
243
|
+
pagina: z.number().int().positive().optional()
|
|
244
|
+
.describe("Número de página (default: 1)"),
|
|
245
|
+
limite: z.number().int().positive().max(100).optional()
|
|
246
|
+
.describe("Registros por página (default: 20, máx: 100)"),
|
|
247
|
+
},
|
|
248
|
+
async ({ empresa, ...rest }) => {
|
|
249
|
+
const resolved = resolveApiKey(empresa);
|
|
250
|
+
if (resolved.error) return err(resolved.error);
|
|
251
|
+
try {
|
|
252
|
+
const result = await callServer(resolved.apiKey, "listar_ausentismo", rest);
|
|
253
|
+
return ok(result);
|
|
254
|
+
} catch (e) {
|
|
255
|
+
return err(`listar_ausentismo: ${e.message}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
server.tool(
|
|
261
|
+
"obtener_ausentismo",
|
|
262
|
+
"Obtiene el detalle completo de un registro de ausentismo por su ID.",
|
|
263
|
+
{
|
|
264
|
+
empresa: empresaField,
|
|
265
|
+
id: z.string().describe("ID único del registro de ausentismo"),
|
|
266
|
+
},
|
|
267
|
+
async ({ empresa, id }) => {
|
|
268
|
+
const resolved = resolveApiKey(empresa);
|
|
269
|
+
if (resolved.error) return err(resolved.error);
|
|
270
|
+
try {
|
|
271
|
+
const result = await callServer(resolved.apiKey, "obtener_ausentismo", { id });
|
|
272
|
+
return ok(result);
|
|
273
|
+
} catch (e) {
|
|
274
|
+
return err(`obtener_ausentismo [${id}]: ${e.message}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
280
|
+
// DIAGNÓSTICO
|
|
281
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
282
|
+
|
|
283
|
+
server.tool(
|
|
284
|
+
"verificar_conexion",
|
|
285
|
+
"Verifica que la conexión con el servidor SIAG esté funcionando correctamente.",
|
|
286
|
+
{
|
|
287
|
+
empresa: empresaField,
|
|
288
|
+
},
|
|
289
|
+
async ({ empresa }) => {
|
|
290
|
+
const resolved = resolveApiKey(empresa);
|
|
291
|
+
if (resolved.error) return err(resolved.error);
|
|
292
|
+
try {
|
|
293
|
+
const result = await callServer(resolved.apiKey, "verificar_conexion");
|
|
294
|
+
return ok(result);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
return err(`verificar_conexion: ${e.message}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
// ─── Arranque ─────────────────────────────────────────────────────────────────
|
|
302
|
+
|
|
303
|
+
async function main() {
|
|
304
|
+
const transport = new StdioServerTransport();
|
|
305
|
+
await server.connect(transport);
|
|
306
|
+
console.error(
|
|
307
|
+
`[SIAG MCP] Servidor iniciado — ` +
|
|
308
|
+
(IS_MULTI
|
|
309
|
+
? `${COMPANY_NAMES.length} empresas: ${COMPANY_NAMES.join(", ")}`
|
|
310
|
+
: `empresa: ${COMPANY_NAMES[0]}`)
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
main().catch((e) => {
|
|
315
|
+
console.error("[SIAG MCP] Error fatal:", e);
|
|
316
|
+
process.exit(1);
|
|
317
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "siag-mcp",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Cliente MCP de SIAG para Claude Desktop — soporte multi-empresa",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"siag-mcp": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node index.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"siag",
|
|
19
|
+
"sgsst",
|
|
20
|
+
"claude",
|
|
21
|
+
"ausentismo",
|
|
22
|
+
"incapacidades"
|
|
23
|
+
],
|
|
24
|
+
"author": "SGSST <soporte@sgsst.co>",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18.14.1"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://gitlab.com/ANSWERCPI9999/siag-mcp-client.git"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
35
|
+
"axios": "^1.13.6",
|
|
36
|
+
"zod": "^4.3.6"
|
|
37
|
+
}
|
|
38
|
+
}
|