@bimatrix-aud-platform/aud_mcp_server 1.1.81 → 1.1.83

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.
@@ -54,6 +54,16 @@ export declare function callModuleService(schemaType: string, params: {
54
54
  Key: string;
55
55
  Value: any[];
56
56
  }[]): Promise<SchemaServiceResult>;
57
+ /**
58
+ * i-AUD 서버의 @RAG_SERVING 서버 스크립트를 호출합니다.
59
+ * 벡터 검색(VECTOR_SEARCH)을 수행합니다.
60
+ * @param schemaType VECTOR_SEARCH
61
+ * @param params 추가 파라미터 (#QUERY#, #CATEGORY#, #API_SIDE#, #TOPICS#, #LIMIT#)
62
+ */
63
+ export declare function callRagService(schemaType: string, params: {
64
+ Key: string;
65
+ Value: any[];
66
+ }[]): Promise<SchemaServiceResult>;
57
67
  /**
58
68
  * i-AUD 서버의 @DBMS_LIST 서버 스크립트를 호출하여
59
69
  * 현재 사용자에게 권한이 있는 DB 연결 목록을 가져옵니다.
@@ -78,6 +88,7 @@ export interface BoxStyleSaveResult {
78
88
  export declare function callBoxStyleSaveService(boxStyle: Record<string, any> | Record<string, any>[]): Promise<BoxStyleSaveResult>;
79
89
  /**
80
90
  * i-AUD 서버에 보고서를 저장(Publish)합니다.
91
+ * 저장 전 서버 파일 변경 충돌 검사를 수행합니다.
81
92
  * VS Code Extension의 submitSaveReportPost와 동일한 역할입니다.
82
93
  */
83
94
  export declare function callSaveReportService(saveModel: Record<string, any>): Promise<any>;
@@ -198,6 +198,49 @@ export function isAudConfigured() {
198
198
  const config = getAudConfig();
199
199
  return !!(config.serviceUrl && config.apiKey && config.userName);
200
200
  }
201
+ /**
202
+ * config 검증 + DataSet.maf URL을 반환합니다.
203
+ */
204
+ function ensureConfig() {
205
+ const config = getAudConfig();
206
+ if (!config.serviceUrl || !config.apiKey) {
207
+ throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
208
+ + "다음 중 하나를 설정해 주세요:\n"
209
+ + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
210
+ + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
211
+ }
212
+ const url = config.serviceUrl
213
+ + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
214
+ return { config, url };
215
+ }
216
+ /**
217
+ * i-AUD 서버에 PACKET을 POST로 전송하고 응답을 반환합니다.
218
+ * 서버 레벨 오류(retCode/retMsg)가 있으면 throw 합니다.
219
+ */
220
+ async function postServiceRequest(config, url, packetStr, hashcodeSuffix) {
221
+ const formBody = new URLSearchParams();
222
+ formBody.append("ENC", "false");
223
+ formBody.append("OUT", "1");
224
+ formBody.append("hashcode", "aud.mcp." + config.userName + (hashcodeSuffix || ""));
225
+ formBody.append("ver", "400");
226
+ formBody.append("PACKET", packetStr);
227
+ const response = await fetch(url, {
228
+ method: "POST",
229
+ headers: {
230
+ "Content-Type": "application/x-www-form-urlencoded",
231
+ "Authorization": "Bearer " + config.apiKey,
232
+ },
233
+ body: formBody.toString(),
234
+ });
235
+ if (!response.ok) {
236
+ throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
237
+ }
238
+ const data = await response.json();
239
+ if (data.retCode && data.retMsg) {
240
+ throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
241
+ }
242
+ return data;
243
+ }
201
244
  /**
202
245
  * PACKET JSON을 구성합니다. (VS Code Extension의 getPacketText와 동일한 구조)
203
246
  */
@@ -231,44 +274,13 @@ function buildPacket(config, scriptCode, script, params) {
231
274
  * i-AUD 서버의 @SCHEMA_SERVICE 서버 스크립트를 호출합니다.
232
275
  */
233
276
  export async function callSchemaService(schemaType, params) {
234
- const config = getAudConfig();
235
- if (!config.serviceUrl || !config.apiKey) {
236
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
237
- + "다음 중 하나를 설정해 주세요:\n"
238
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
239
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
240
- }
277
+ const { config, url } = ensureConfig();
241
278
  const allParams = [
242
279
  { Key: "#SCHEMA_TYPE#", Value: [schemaType] },
243
280
  ...params,
244
281
  ];
245
- const url = config.serviceUrl
246
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
247
282
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@SCHEMA_SERVICE", SERVICE_SOURCE_LIST.SCHEMA_SERVICE, allParams);
248
- // multipart/form-data 형식으로 전송 (VS Code Extension과 동일)
249
- const formBody = new URLSearchParams();
250
- formBody.append("ENC", "false");
251
- formBody.append("OUT", "1");
252
- formBody.append("hashcode", "aud.mcp." + config.userName + generateId("."));
253
- formBody.append("ver", "400");
254
- formBody.append("PACKET", packetStr);
255
- const response = await fetch(url, {
256
- method: "POST",
257
- headers: {
258
- "Content-Type": "application/x-www-form-urlencoded",
259
- "Authorization": "Bearer " + config.apiKey,
260
- },
261
- body: formBody.toString(),
262
- });
263
- if (!response.ok) {
264
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
265
- }
266
- const data = await response.json();
267
- // 서버 레벨 오류 체크
268
- if (data.retCode && data.retMsg) {
269
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
270
- }
271
- return data;
283
+ return await postServiceRequest(config, url, packetStr, generateId("."));
272
284
  }
273
285
  /**
274
286
  * i-AUD 서버의 @MODULE_SERVICE 서버 스크립트를 호출합니다.
@@ -277,241 +289,114 @@ export async function callSchemaService(schemaType, params) {
277
289
  * @param params 추가 파라미터
278
290
  */
279
291
  export async function callModuleService(schemaType, params) {
280
- const config = getAudConfig();
281
- if (!config.serviceUrl || !config.apiKey) {
282
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
283
- + "다음 중 하나를 설정해 주세요:\n"
284
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
285
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
286
- }
292
+ const { config, url } = ensureConfig();
287
293
  const allParams = [
288
294
  { Key: "#SCHEMA_TYPE#", Value: [schemaType] },
289
295
  ...params,
290
296
  ];
291
- const url = config.serviceUrl
292
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
293
297
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@MODULE_SERVICE", SERVICE_SOURCE_LIST.MODULE_SERVICE, allParams);
294
- // multipart/form-data 형식으로 전송 (VS Code Extension과 동일)
295
- const formBody = new URLSearchParams();
296
- formBody.append("ENC", "false");
297
- formBody.append("OUT", "1");
298
- formBody.append("hashcode", "aud.mcp." + config.userName);
299
- formBody.append("ver", "400");
300
- formBody.append("PACKET", packetStr);
301
- const response = await fetch(url, {
302
- method: "POST",
303
- headers: {
304
- "Content-Type": "application/x-www-form-urlencoded",
305
- "Authorization": "Bearer " + config.apiKey,
306
- },
307
- body: formBody.toString(),
308
- });
309
- if (!response.ok) {
310
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
311
- }
312
- const data = await response.json();
313
- // 서버 레벨 오류 체크
314
- if (data.retCode && data.retMsg) {
315
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
316
- }
317
- return data;
298
+ return await postServiceRequest(config, url, packetStr);
299
+ }
300
+ /**
301
+ * i-AUD 서버의 @RAG_SERVING 서버 스크립트를 호출합니다.
302
+ * 벡터 검색(VECTOR_SEARCH)을 수행합니다.
303
+ * @param schemaType VECTOR_SEARCH
304
+ * @param params 추가 파라미터 (#QUERY#, #CATEGORY#, #API_SIDE#, #TOPICS#, #LIMIT#)
305
+ */
306
+ export async function callRagService(schemaType, params) {
307
+ const { config, url } = ensureConfig();
308
+ const allParams = [
309
+ { Key: "#SCHEMA_TYPE#", Value: [schemaType] },
310
+ ...params,
311
+ ];
312
+ const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@RAG_SERVING", SERVICE_SOURCE_LIST.RAG_SERVING, allParams);
313
+ return await postServiceRequest(config, url, packetStr);
318
314
  }
319
315
  /**
320
316
  * i-AUD 서버의 @DBMS_LIST 서버 스크립트를 호출하여
321
317
  * 현재 사용자에게 권한이 있는 DB 연결 목록을 가져옵니다.
322
318
  */
323
319
  export async function callDbmsList() {
324
- const config = getAudConfig();
325
- if (!config.serviceUrl || !config.apiKey) {
326
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
327
- + "다음 중 하나를 설정해 주세요:\n"
328
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
329
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
330
- }
331
- const url = config.serviceUrl
332
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
320
+ const { config, url } = ensureConfig();
333
321
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@DBMS_LIST", SERVICE_SOURCE_LIST.DBMS_LIST, []);
334
- const formBody = new URLSearchParams();
335
- formBody.append("ENC", "false");
336
- formBody.append("OUT", "1");
337
- formBody.append("hashcode", "aud.mcp." + config.userName);
338
- formBody.append("ver", "400");
339
- formBody.append("PACKET", packetStr);
340
- const response = await fetch(url, {
341
- method: "POST",
342
- headers: {
343
- "Content-Type": "application/x-www-form-urlencoded",
344
- "Authorization": "Bearer " + config.apiKey,
345
- },
346
- body: formBody.toString(),
347
- });
348
- if (!response.ok) {
349
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
350
- }
351
- const data = await response.json();
352
- if (data.retCode && data.retMsg) {
353
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
354
- }
355
- return data;
322
+ return await postServiceRequest(config, url, packetStr);
356
323
  }
357
324
  /**
358
325
  * i-AUD 서버의 @BOXSTYLE_LIST 서버 스크립트를 호출하여
359
326
  * BoxStyle 목록을 가져옵니다.
360
327
  */
361
328
  export async function callBoxStyleService() {
362
- const config = getAudConfig();
363
- if (!config.serviceUrl || !config.apiKey) {
364
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
365
- + "다음 중 하나를 설정해 주세요:\n"
366
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
367
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
368
- }
369
- const url = config.serviceUrl
370
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
329
+ const { config, url } = ensureConfig();
371
330
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@BOXSTYLE_LIST", SERVICE_SOURCE_LIST.BOXSTYLE_LIST, []);
372
- const formBody = new URLSearchParams();
373
- formBody.append("ENC", "false");
374
- formBody.append("OUT", "1");
375
- formBody.append("hashcode", "aud.mcp." + config.userName);
376
- formBody.append("ver", "400");
377
- formBody.append("PACKET", packetStr);
378
- const response = await fetch(url, {
379
- method: "POST",
380
- headers: {
381
- "Content-Type": "application/x-www-form-urlencoded",
382
- "Authorization": "Bearer " + config.apiKey,
383
- },
384
- body: formBody.toString(),
385
- });
386
- if (!response.ok) {
387
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
388
- }
389
- const data = await response.json();
390
- if (data.retCode && data.retMsg) {
391
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
392
- }
393
- return data;
331
+ return await postServiceRequest(config, url, packetStr);
394
332
  }
395
333
  /**
396
334
  * i-AUD 서버에 BoxStyle을 저장(생성/수정)합니다.
397
335
  * 단일 객체 또는 배열을 전달할 수 있습니다.
398
336
  */
399
337
  export async function callBoxStyleSaveService(boxStyle) {
400
- const config = getAudConfig();
401
- if (!config.serviceUrl || !config.apiKey) {
402
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
403
- + "다음 중 하나를 설정해 주세요:\n"
404
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
405
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
406
- }
407
- const url = config.serviceUrl
408
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
338
+ const { config, url } = ensureConfig();
409
339
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@BOXSTYLE_SAVE", SERVICE_SOURCE_LIST.BOXSTYLE_SAVE, [
410
340
  { Key: "#BOXSTYLE_DATA#", Value: [JSON.stringify(boxStyle)] },
411
341
  ]);
412
- const formBody = new URLSearchParams();
413
- formBody.append("ENC", "false");
414
- formBody.append("OUT", "1");
415
- formBody.append("hashcode", "aud.mcp." + config.userName);
416
- formBody.append("ver", "400");
417
- formBody.append("PACKET", packetStr);
418
- const response = await fetch(url, {
419
- method: "POST",
420
- headers: {
421
- "Content-Type": "application/x-www-form-urlencoded",
422
- "Authorization": "Bearer " + config.apiKey,
423
- },
424
- body: formBody.toString(),
425
- });
426
- if (!response.ok) {
427
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
342
+ return await postServiceRequest(config, url, packetStr);
343
+ }
344
+ /**
345
+ * 저장 전 서버의 보고서 수정일자를 확인하여 충돌 여부를 검사합니다.
346
+ * 서버 파일이 로컬보다 최근에 수정되었으면 에러를 throw 합니다.
347
+ */
348
+ async function callCheckSaveService(config, url, reportCode, clientEditDate) {
349
+ const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@CHECK_SAVE", SERVICE_SOURCE_LIST.CHECK_SAVE || "", [
350
+ { Key: "VS_REPORT_CODE", Value: [reportCode] },
351
+ { Key: "VS_EDIT_DATE", Value: [clientEditDate] },
352
+ ]);
353
+ try {
354
+ const data = await postServiceRequest(config, url, packetStr);
355
+ let result = data;
356
+ if (typeof data === "string") {
357
+ result = JSON.parse(data);
358
+ }
359
+ if (result.Success === false) {
360
+ throw new Error(result.Message);
361
+ }
428
362
  }
429
- const data = await response.json();
430
- if (data.retCode && data.retMsg) {
431
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
363
+ catch (e) {
364
+ // postServiceRequest의 서버 오류(retCode/retMsg) 에러 메시지만 출력하고 저장 진행
365
+ if (e.message?.includes("i-AUD 서버 오류")) {
366
+ process.stderr.write(`[aud_mcp_server] checkSaveConflict server error: ${e.message}\n`);
367
+ return;
368
+ }
369
+ throw e;
432
370
  }
433
- return data;
434
371
  }
435
372
  /**
436
373
  * i-AUD 서버에 보고서를 저장(Publish)합니다.
374
+ * 저장 전 서버 파일 변경 충돌 검사를 수행합니다.
437
375
  * VS Code Extension의 submitSaveReportPost와 동일한 역할입니다.
438
376
  */
439
377
  export async function callSaveReportService(saveModel) {
440
- const config = getAudConfig();
441
- if (!config.serviceUrl || !config.apiKey) {
442
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
443
- + "다음 하나를 설정해 주세요:\n"
444
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
445
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
446
- }
447
- const url = config.serviceUrl
448
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
378
+ const { config, url } = ensureConfig();
379
+ // 1. 저장 충돌 검사
380
+ const reportCode = saveModel.REPORT_CODE || "";
381
+ const clientEditDate = saveModel.ReportModel?.ReportInfo?.EditDate || "";
382
+ await callCheckSaveService(config, url, reportCode, clientEditDate);
383
+ // 2. 서버 전송
449
384
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@SAVE_REPORT", SERVICE_SOURCE_LIST.SAVE_REPORT, [
450
385
  { Key: "VS_REPORT_INFO", Value: [JSON.stringify(saveModel)] },
451
386
  ]);
452
- const formBody = new URLSearchParams();
453
- formBody.append("ENC", "false");
454
- formBody.append("OUT", "1");
455
- formBody.append("hashcode", "aud.mcp." + config.userName);
456
- formBody.append("ver", "400");
457
- formBody.append("PACKET", packetStr);
458
- const response = await fetch(url, {
459
- method: "POST",
460
- headers: {
461
- "Content-Type": "application/x-www-form-urlencoded",
462
- "Authorization": "Bearer " + config.apiKey,
463
- },
464
- body: formBody.toString(),
465
- });
466
- if (!response.ok) {
467
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
468
- }
469
- const data = await response.json();
470
- if (data.retCode && data.retMsg) {
471
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
472
- }
473
- return data;
387
+ return await postServiceRequest(config, url, packetStr);
474
388
  }
475
389
  /**
476
390
  * i-AUD 서버에서 보고서를 읽어옵니다 (Pull).
477
391
  * VS Code Extension의 submitReadReportPost와 동일한 역할입니다.
478
392
  */
479
393
  export async function callReadReportService(reportCode) {
480
- const config = getAudConfig();
481
- if (!config.serviceUrl || !config.apiKey) {
482
- throw new Error("i-AUD 서버 접속 정보를 찾을 수 없습니다.\n"
483
- + "다음 중 하나를 설정해 주세요:\n"
484
- + " 1) .vscode/settings.json의 aud.config (ServiceURL, ApiKey, UserName)\n"
485
- + " 2) 환경변수: AUD_SERVICE_URL, AUD_API_KEY, AUD_USER_NAME");
486
- }
487
- const url = config.serviceUrl
488
- + (config.serviceUrl.endsWith("/") ? "servlet/DataSet.maf" : "/servlet/DataSet.maf");
394
+ const { config, url } = ensureConfig();
489
395
  const packetStr = buildPacket(config, "@AUD_SAVE_SERVICE@READ_REPORT", SERVICE_SOURCE_LIST.READ_REPORT, [
490
396
  { Key: "VS_REPORT_CODE", Value: [reportCode] },
491
397
  { Key: "VS_REPORT_NAME", Value: [""] },
492
398
  ]);
493
- const formBody = new URLSearchParams();
494
- formBody.append("ENC", "false");
495
- formBody.append("OUT", "1");
496
- formBody.append("hashcode", "aud.mcp." + config.userName);
497
- formBody.append("ver", "400");
498
- formBody.append("PACKET", packetStr);
499
- const response = await fetch(url, {
500
- method: "POST",
501
- headers: {
502
- "Content-Type": "application/x-www-form-urlencoded",
503
- "Authorization": "Bearer " + config.apiKey,
504
- },
505
- body: formBody.toString(),
506
- });
507
- if (!response.ok) {
508
- throw new Error(`i-AUD 서버 요청 실패: HTTP ${response.status} ${response.statusText}`);
509
- }
510
- const data = await response.json();
511
- if (data.retCode && data.retMsg) {
512
- throw new Error(`i-AUD 서버 오류: [${data.retCode}] ${data.retMsg}`);
513
- }
514
- return data;
399
+ return await postServiceRequest(config, url, packetStr);
515
400
  }
516
401
  /**
517
402
  * MX_GRID 리소스 파일을 서버에서 다운로드하고 압축을 풀어 로컬에 저장합니다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bimatrix-aud-platform/aud_mcp_server",
3
- "version": "1.1.81",
3
+ "version": "1.1.83",
4
4
  "description": "MCP Server for i-AUD MTSD document validation, generation, schema querying, control info extraction, and database operations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",