64 Commits

Author SHA1 Message Date
jade
0b187d6fd1 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 41s
2026-09-17 18:03:35 +09:00
jade
5955c2168e 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m6s
2026-09-17 17:32:46 +09:00
jade
244bfade74 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	dat-was-lib/src/main/java/io/shinhanlife/dat/lib/util/ToolScaffolder.java
#	dat-was-pro/src/main/java/io/shinhanlife/dat/mcc/biz/pro/converter/RecruitmentFeeDisclosureDataConverter.java
#	dat-was-pro/src/main/java/io/shinhanlife/dat/mcc/biz/pro/dto/RecruitmentFeeDisclosureDataRequest.java
#	dat-was-sal/Dockerfile
#	dat-was-sal/build.gradle
#	dat-was-sal/src/main/java/io/shinhanlife/dat/mcc/sal/DatWasSalApplication.java
#	dat-was-sal/src/main/resources/application-dev.yml
#	dat-was-sal/src/main/resources/application-local.yml
#	dat-was-sal/src/main/resources/application-prod.yml
#	dat-was-sal/src/main/resources/application-test.yml
#	dat-was-sal/src/main/resources/application.yml
#	dat-was-sal/src/main/resources/logback-spring.xml
#	dat-was-sal/src/main/resources/tool-service-manifest.yml
2026-09-17 17:32:18 +09:00
jade
a8555f05af 소스 업데이트 2026-09-17 17:31:37 +09:00
jade
5f58c22efe feat: extract MciPagingUtils and update ToolScaffolder
All checks were successful
Deploy Tools / deploy (push) Successful in 1m30s
2026-09-17 10:22:25 +09:00
jade
ae8ab85016 feat: add CommonCodeResolver, codes.csv and RecruitmentFeeDisclosureData companyCode mapping
All checks were successful
Deploy Tools / deploy (push) Successful in 1m24s
2026-09-17 08:53:30 +09:00
jade
d2a82db6a4 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m25s
2026-09-10 13:28:40 +09:00
jade
f3099b76ea 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m35s
2026-09-08 09:24:11 +09:00
jade
82551d87bb 소스 업데이트
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-09-08 09:24:05 +09:00
jade
f80461a071 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m23s
2026-09-07 11:02:05 +09:00
jade
bb6cbab912 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m25s
2026-09-07 10:26:27 +09:00
jade
93111b430a 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 2m16s
2026-09-03 10:50:41 +09:00
jade
38462b8ad7 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 2m21s
2026-09-02 17:50:08 +09:00
jade
b6603d7449 fix: align tool service routing manifest schema
All checks were successful
Deploy Tools / deploy (push) Successful in 1m24s
2026-09-02 14:34:35 +09:00
jade
10aa14ccf4 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m38s
2026-09-02 13:32:32 +09:00
jade
d0471dfc6a feat: add tool service manifest and scaffold generation
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-09-02 13:29:29 +09:00
jade
62a05bf18a chore: align compose and k8s tool services
All checks were successful
Deploy Tools / deploy (push) Successful in 1m24s
2026-09-02 09:44:05 +09:00
jade
a5ac2f99eb docs: update DATMT README for tool metadata
All checks were successful
Deploy Tools / deploy (push) Successful in 2m12s
2026-08-31 17:06:06 +09:00
jade
96c0b779e6 fix: resolve PascalCase generation issue for all-caps strings in ToolScaffolder
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-08-31 17:03:38 +09:00
jade
032b639291 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m26s
2026-08-31 16:39:16 +09:00
jade
42a04c03fd fix: safely rename dasmt to datmt without breaking encoding
All checks were successful
Deploy Tools / deploy (push) Successful in 2m46s
2026-08-31 15:55:43 +09:00
jade
cd991bd623 Revert "refactor: rename dasmt to datmt across the project"
This reverts commit 740ef1c757.
2026-08-31 15:55:13 +09:00
jade
740ef1c757 refactor: rename dasmt to datmt across the project
All checks were successful
Deploy Tools / deploy (push) Successful in 1m11s
2026-08-31 13:21:33 +09:00
jade
8b9bd4de16 refactor: remove retryEnabled from tool metadata 2026-08-31 10:12:31 +09:00
jade
6a6592f2d5 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m24s
2026-08-31 09:57:03 +09:00
jade
0fcbef043b feat: expose tool timeout and retry metadata
All checks were successful
Deploy Tools / deploy (push) Successful in 1m27s
2026-08-31 09:51:56 +09:00
윤희준
0921e6d85d Fix Dockerfile paths and add main to ValidationRunner
Some checks failed
Deploy Tools / deploy (push) Failing after 34s
2026-08-28 16:10:45 +09:00
윤희준
3498dbb388 Disable bootJar for root project
All checks were successful
Deploy Tools / deploy (push) Successful in 1m42s
2026-08-28 15:59:05 +09:00
윤희준
f7ffc00b36 Fix root project repository for dependency management
All checks were successful
Deploy Tools / deploy (push) Successful in 1m38s
2026-08-28 15:32:28 +09:00
jade
bd8db994ce 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m33s
2026-08-27 14:19:32 +09:00
jade
6479b56c8e 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 2m16s
2026-08-27 13:09:16 +09:00
jade
eff142b956 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 55s
2026-08-27 09:02:49 +09:00
jade
935702a569 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 52s
2026-08-25 17:49:04 +09:00
jade
87249a621c 소스 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 1m30s
2026-08-25 17:42:41 +09:00
jade
d3cc1f7f33 feat: update MCP contracts and integrations
All checks were successful
Deploy Tools / deploy (push) Successful in 1m34s
2026-08-25 16:37:08 +09:00
jade
53bc1487c8 Merge branch 'main' of https://git.devjun.net/AX-HUB/dap-was-dapmt
All checks were successful
Deploy Tools / deploy (push) Successful in 1m4s
2026-08-25 13:09:08 +09:00
jade
5080887f8b 소스 업데이트 2026-08-25 13:02:58 +09:00
jade
ba2f43cd60 feat: add OpenShift deployment manifests
All checks were successful
Deploy Tools / deploy (push) Successful in 2m9s
2026-08-21 11:27:45 +09:00
jade
b617eaabe4 docs: update DATMT deployment guide
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-08-21 11:26:57 +09:00
jade
540faff2d8 gradle 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 52s
2026-08-20 15:35:50 +09:00
jade
311462d613 gradle 업데이트
All checks were successful
Deploy Tools / deploy (push) Successful in 50s
2026-08-20 15:18:47 +09:00
jade
11738a9e89 fix: resolve PodScaffolder missing workspace path by reading AXHUB_SOURCE_DIR system property instead of just env var
All checks were successful
Deploy Tools / deploy (push) Successful in 1m58s
2026-08-20 13:32:30 +09:00
jade
b71c585cd7 fix: resolve remaining baseName placeholders for MCI IO files in grouped append and converter generators
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-08-20 13:31:40 +09:00
jade
ded9fac9ef fix: replace missed baseName placeholders for MCI IO files and UseCaseImpl integration packages
All checks were successful
Deploy Tools / deploy (push) Successful in 2m13s
2026-08-20 13:17:00 +09:00
jade
c9a04d031a fix: resolve mci package splitting and IO class naming issues in ToolScaffolder
All checks were successful
Deploy Tools / deploy (push) Successful in 2m25s
2026-08-20 13:04:06 +09:00
jade
fdf9e91b0a gateway service 수정
All checks were successful
Deploy Tools / deploy (push) Successful in 2m19s
2026-08-20 12:52:42 +09:00
jade
7389c6380c refactor: massive rename dap -> dat and dapmt -> datmt preserving encoding
All checks were successful
Deploy Tools / deploy (push) Successful in 1m21s
2026-08-20 10:41:55 +09:00
jade
7f84dd848b fix(scaffold): format 4-char MCI system code paths (e.g. hmc.i) and unify grouped tool client
All checks were successful
Deploy Tools / deploy (push) Successful in 2m23s
- For 4-character client system codes like 'hmci', the path is now split as 'hmc/i' to generate packages like 'hmc.i'
- MultiTool UseCase scaffolding now correctly reuses the shared Mci[Prefix]Client (e.g. MciHmciClient) instead of generating separate tool-specific clients
2026-08-20 09:34:22 +09:00
jade
2db5be1f67 fix(scaffold): respect AXHUB_SOURCE_DIR property for Pod generation
All checks were successful
Deploy Tools / deploy (push) Successful in 1m28s
- PodScaffolder now checks System.getProperty before System.getenv for dynamic targeting.
2026-08-20 09:23:55 +09:00
jade
318a6ba8d9 fix: make AxhubSessionService optional to prevent Gateway crash
All checks were successful
Deploy Tools / deploy (push) Successful in 2m22s
2026-08-19 17:21:22 +09:00
jade
6416e0e499 fix: add DRTM_CD and USER_ID to HeaderDefaults
All checks were successful
Deploy Tools / deploy (push) Successful in 2m28s
2026-08-19 17:13:56 +09:00
jade
a7450cb1db feat: align AxhubMciComponent with TmMciComponent (DRTM_CD, USER_ID, BizException)
All checks were successful
Deploy Tools / deploy (push) Successful in 1m52s
2026-08-19 17:08:44 +09:00
jade
fe1ed9ea65 fix: import path for GlowTrgmField
All checks were successful
Deploy Tools / deploy (push) Successful in 1m32s
2026-08-19 16:45:35 +09:00
jade
2e9a0d6005 feat: implement MCI session fetching using employee number
All checks were successful
Deploy Tools / deploy (push) Successful in 1m28s
2026-08-19 16:41:01 +09:00
jade
a8363fae1e fix: refactor ToolScaffolder to use generic MciClient for MCI tools
All checks were successful
Deploy Tools / deploy (push) Successful in 1m32s
2026-08-19 14:06:45 +09:00
jade
9dcf06ae95 fix: resolve workspace path resolution and enhance GrowToolHint generation in ToolScaffolder
All checks were successful
Deploy Tools / deploy (push) Successful in 1m49s
2026-08-19 13:51:03 +09:00
jade
317f9865b8 fix: include pattern in mcp tool schema generation and scaffold output
All checks were successful
Deploy Tools / deploy (push) Successful in 2m20s
2026-08-19 10:31:46 +09:00
jade
6646741665 refactor: migrate all tools in sal, pro, cus to @GrowToolHint and remove obsolete tests
All checks were successful
Deploy Tools / deploy (push) Successful in 2m25s
2026-08-18 22:09:39 +09:00
jade
a50c425dba test(was-sys): remove obsolete SystemMockToolResourcesTest after YAML migration
Some checks failed
Deploy Tools / deploy (push) Has been cancelled
2026-08-18 22:08:13 +09:00
jade
96369f8fb5 refactor(was-sys): migrate all 49 tools from YAML definitions to @GrowToolHint annotations
All checks were successful
Deploy Tools / deploy (push) Successful in 2m23s
2026-08-18 22:04:43 +09:00
jade
1560589dd5 feat(was-lib): map GrowToolHint metadata fields to ToolMetadata in ToolScanner
All checks were successful
Deploy Tools / deploy (push) Successful in 2m21s
2026-08-18 22:00:21 +09:00
jade
90cf757b5e refactor(was-sys): migrate iam_access_policy tool metadata from YAML to @GrowToolHint annotation
All checks were successful
Deploy Tools / deploy (push) Successful in 1m23s
2026-08-18 21:58:34 +09:00
jade
784d00d61c feat(was-sys): add TeamContactUseCase with branching logic
All checks were successful
Deploy Tools / deploy (push) Successful in 1m37s
2026-08-18 21:25:23 +09:00
jade
e200dbd5b8 use bundleId to dynamically match module-wide tool manifest requests
All checks were successful
Deploy Tools / deploy (push) Successful in 7m42s
2026-08-18 21:01:01 +09:00
659 changed files with 692 additions and 21672 deletions

458
README.md
View File

@@ -1,400 +1,72 @@
# DAP WAS MCP Tool Pods
# 신한라이프 시스템 도메인 Tool Pod (dat-was-datsy)
신한라이프 업무 기능을 MCP(Model Context Protocol) Tool로 제공하는 Java 멀티 모듈 프로젝트입니다. 각 업무 모듈은 독립 실행 가능한 Spring Boot 애플리케이션이며, MCP Streamable HTTP와 REST 실행 API를 함께 제공합니다.
신한라이프 DX그룹 PJT **MCP & TOOL 파트**에서 개발 및 운영하는 시스템(SYS) 도메인 전용 DATMT Tool Service Pod(`dat-was-sys`)입니다.
IAM(계정·인증·인가 및 담당자 조회)과 PCT(점검 일정, 릴리즈 이력, 시스템 공지사항 등) 영역에서 AI Agent가 시스템 운영 현황을 파악하고 질의응답을 지원할 수 있는 MCP 도구를 제공합니다.
이 저장소에는 DAPMS(Gateway) 애플리케이션이 포함되어 있지 않습니다. DAPMT는 Gateway로 Tool을 push 등록하지 않으며, 각 Pod가 `GET /tool-manifest`를 제공하면 DAPMS가 이 Manifest를 pull하여 Tool 목록을 구성합니다. Tool 조회와 직접 실행은 각 Pod에서도 자체적으로 처리합니다.
---
## 기술 기준
## 1. 서비스 사양 요약
- Java 21
- Gradle Wrapper 8.14.3
- Spring Boot 3.5.11
- MCP Java SDK 2.0.0
- Spring AI Community MCP Annotations 0.9.0
- Jackson 2.20.1
- MapStruct, MyBatis, Redis, Kafka, Resilience4j
- JUnit 5
## 모듈 구성
| 모듈 | 역할 | 기본 포트 | Tool 수 |
|---|---|---:|---:|
| `dap-was-lib` | MCP 서버, Tool 스캔·실행, Schema, Manifest, 보안, MCI/EAI/HTTP 연동 공통 기능 | - | - |
| `dap-was-cus` | 고객·CRM·VOC·웹 콘텐츠 관리 Tool | 8084 | 51 |
| `dap-was-sal` | 영업·청구·인수·동의·현장지원 Tool | 8082 | 52 |
| `dap-was-pro` | 상품·계약·고객·GA 설계사 Tool | 8085 | 50 |
| `dap-was-sys` | IAM·시스템 상태·공지·점검·배포 Tool | 8086 | 50 |
총 203개의 `@McpTool` 선언과 203개의 V17 Tool YAML 정의가 있습니다.
현재 업무 구현은 개발·연동 검증 단계입니다. `dap-was-sal``cmm_claim_search``cmm_memo_retriever`는 각각 MCI와 HTTP Client 흐름을 사용하며, 나머지 Tool은 외부 시스템을 변경하지 않는 모의 응답을 중심으로 구현되어 있습니다.
## 처리 구조
```text
MCP Client 또는 REST Client
├─ MCP Streamable HTTP: /mcp
└─ REST: POST /mcp/{toolName}
Tool Pod
├─ McpToolMethodRegistry
│ └─ Spring Bean의 @McpTool 메서드 탐색 및 실행 메서드 캐시
├─ ToolRegistryHeartbeatSender
│ ├─ Tool 메타데이터 생성
│ └─ tool-definitions YAML 병합
├─ ToolManifestService
│ └─ DAPMS가 pull할 bundle 단위 Manifest 생성
├─ McpToolExecutionService
│ ├─ 입력 Schema 검증
│ ├─ 요청 DTO 변환 및 Tool 호출
│ └─ 출력 Schema 검증
└─ UseCase → Converter → MCI/EAI/HTTP Client 또는 Mock 응답
```
애플리케이션 시작 시 다음 순서로 Tool이 준비됩니다.
1. `ToolDefinitionRepository``classpath*:tool-definitions/**/*.yml`을 읽고 V17 필수 항목을 검증합니다.
2. `ToolRegistryHeartbeatSender``@McpTool` 메서드를 스캔하고 YAML 정의를 병합해 `ToolMetadata`를 생성합니다.
3. `McpToolMethodRegistry`가 실제 호출 가능한 Bean과 메서드를 Tool 이름으로 캐시합니다.
4. `ToolPodMcpToolSynchronizer`가 Tool을 MCP SDK 서버에 등록합니다.
5. REST와 MCP 요청은 공통 `McpToolExecutionService`를 통해 실행됩니다.
DAPMT 내부에는 `/registry/register`, `/registry/deregister` 호출이나 주기적인 Gateway heartbeat 전송이 없습니다. `ToolRegistryHeartbeatSender`라는 클래스명은 호환성을 위해 남아 있지만 현재 역할은 로컬 Tool 스캔과 메타데이터 생성뿐입니다.
### DAPMS 연동 방식
```text
DAPMS
└─ GET {DAPMT Pod URL}/tool-manifest
└─ bundleId + revision + tools[]
└─ 각 Tool endpoint: {Pod URL}/mcp/{toolName}
```
- `mcp.manifest.bundle-id`는 Manifest를 제공하는 Pod의 고유 식별자이며 필수입니다.
- 현재 값은 `was-sal`, `was-cus`, `was-pro`, `was-sys`입니다.
- DAPMS에 설정한 bundle ID와 DAPMT가 반환하는 `bundleId`가 일치해야 같은 Tool bundle로 관리됩니다.
- `mcp.manifest.name-prefix`가 비어 있지 않으면 모든 Tool 이름이 해당 prefix로 시작해야 합니다.
- Manifest 내용이 바뀌면 `revision`이 증가하며, `If-None-Match`가 일치하면 `304 Not Modified`를 반환합니다.
## 제공 API
각 업무 Pod가 동일한 API 구조를 제공합니다.
| 목적 | 메서드 | 경로 |
|---|---|---|
| MCP Streamable HTTP | MCP 프로토콜 | `/mcp` |
| MCP 메시지 전송 | MCP 프로토콜 | `/mcp/message` |
| 로컬 Tool 메타데이터 조회 | `GET` | `/mcp/api/v1/tools/local` |
| Tool 직접 실행 | `POST` | `/mcp/{toolName}` |
| Tool Manifest 조회 | `GET` | `/tool-manifest` |
`GET /tool-manifest``If-None-Match` 요청 헤더를 지원합니다. Manifest가 변경되지 않았으면 `304 Not Modified`를 반환합니다.
### REST 실행 예시
다음은 SYS Pod의 시스템 상태 Tool 호출 예시입니다.
```powershell
$headers = @{
'X-Tool-Server-API-Key' = $env:TOOL_SERVER_API_KEY
'guid' = 'guid-local-001'
'x-request-id' = 'request-local-001'
'employee-no' = '100001'
'virtual-employee-no' = 'V100001'
'mcp-session-id' = 'session-local-001'
}
Invoke-RestMethod `
-Method Post `
-Uri 'http://localhost:8086/mcp/iam_system_status' `
-Headers $headers `
-ContentType 'application/json' `
-Body '{"environment":"개발"}'
```
### 요청 헤더 계약
DAPMS가 DAPMT Tool Service를 호출할 때 사용하는 헤더는 다음과 같습니다. HTTP 헤더 이름은 대소문자를 구분하지 않지만, 문서와 구현에서는 아래 표기를 기준으로 사용합니다.
| 헤더 | 필수 여부 | 용도 | 전달 동작 |
|---|---|---|---|
| `X-Tool-Server-API-Key` | 인증 설정 시 필수 | DAPMS와 DAPMT 사이의 Tool Server 인증 | `mcp.security.api-key` 또는 `api-keys`와 비교 |
| `guid` | 선택 | 업무 호출 상관관계 식별자 | 실행 로그, 성공 응답, 하위 HTTP 호출로 전달 |
| `x-request-id` | 선택 | 요청 추적 식별자 | 실행 로그, 성공 응답, 하위 HTTP 호출로 전달 |
| `employee-no` | 선택 | 실제 사용자 사번 | 하위 HTTP 호출로 전달 |
| `virtual-employee-no` | 선택 | 가상 사용자 사번 | 하위 HTTP 호출로 전달 |
| `mcp-session-id` | 선택 | MCP 세션 식별자 | 성공 응답과 하위 HTTP 호출로 전달 |
REST 경로 `/mcp/{toolName}`은 Controller가 위 헤더를 직접 읽습니다. MCP Streamable HTTP 경로 `/mcp``McpRequestHeaderFilter`가 동일한 헤더를 `McpRequestHeaderContext`에 저장한 뒤 Tool 실행과 하위 HTTP 호출에 전달합니다. 헤더가 없는 하위 HTTP 호출에는 `X-ANONYMOUS-REQ: AXHUB-TOOL`이 설정됩니다.
주요 실행 응답은 다음과 같습니다.
| HTTP 상태 | 코드 | 의미 |
|---:|---|---|
| 200 | - | Tool 실행 성공 |
| 404 | `TOOL_NOT_FOUND` | 요청한 Tool 이름이 없음 |
| 422 | `INVALID_PARAM` | 요청이 입력 Schema와 일치하지 않음 |
| 500 | `INVALID_TOOL_RESPONSE` | 결과가 출력 Schema와 일치하지 않음 |
| 502 | `TOOL_ERROR` | Tool 실행 중 예외 발생 |
## Tool 구현 방식
호출 가능한 메서드는 Spring AI Community의 `@McpTool`로 선언합니다. 프로젝트 고유 실행·표시 정보는 `@GrowToolHint`로 보완합니다.
```java
@McpTool(
name = "iam_system_status",
title = "시스템 상태 조회",
description = "모의 시스템 상태 정보를 조회합니다.",
annotations = @McpTool.McpAnnotations(openWorldHint = false)
)
@GrowToolHint(
categoryKey = "iam",
mappingId = "DIRECT_IAM_STATUS",
requiresApproval = false
)
SystemStatusResponse getSystemStatus(SystemStatusRequest request);
```
`@McpTool.name`은 다음 형식을 사용합니다.
```text
^[a-z][a-z0-9_]{2,63}$
```
예: `cmm_claim_search`, `crm_customer_detail`, `iam_system_status`
이름 중복과 형식은 `validateMcpToolNames`, V17 정의는 `validateToolSchemaV17` Gradle 작업으로 검사합니다. 모든 `bootJar` 작업은 두 검증 작업에 의존합니다.
## Tool YAML 정의
각 Tool은 업무 모듈의 다음 경로에 YAML 정의를 가집니다.
```text
dap-was-*/src/main/resources/tool-definitions/{category}/{tool-name}.yml
```
V17 정의의 주요 필수 항목은 다음과 같습니다.
- `name`, `display_name`, `version`, `category_key`
- `description.function`, `when_to_use`, `when_not_to_use`, `io_limits`
- 3~10개의 `example_queries`
- `read_only`, `destructive`, `idempotent`
- `parameters_schema.type: object`
- `parameters_schema.additionalProperties: false`
- 각 입력 property의 `description`
입력·출력 Schema는 `ToolSchemaResolver`가 어노테이션의 Schema 리소스와 인라인 Schema, DTO에서 생성한 Schema를 해석합니다. `ToolRegistryHeartbeatSender`는 여기에 YAML의 `parameters_schema``output_schema`를 병합하여 최종 메타데이터를 만듭니다.
실행 시 Schema 검증은 MCP Java SDK의 `DefaultJsonSchemaValidator`를 사용하며 JSON Schema 2020-12 기준으로 처리합니다. 입력 불일치는 `422 INVALID_PARAM`, 출력 불일치는 `500 INVALID_TOOL_RESPONSE`로 반환됩니다. 단, Schema 해석 또는 검증기 자체에서 예외가 발생하면 현재 구현은 오류를 로그에 기록하고 해당 검증을 건너뜁니다.
## 로컬 실행
### 사전 조건
- JDK 21
- 프로젝트에 포함된 Gradle Wrapper
- Redis 또는 외부 연동이 필요한 경우 Docker
기본 활성 프로필은 `local`입니다. 로컬 프로필은 H2 메모리 DB와 P6Spy를 사용합니다.
```powershell
$env:SPRING_PROFILES_ACTIVE = 'local'
$env:TOOL_SERVER_API_KEY = 'tool-server-key'
```
`TOOL_SERVER_API_KEY`를 지정하지 않으면 현재 개발 기본값인 `tool-server-key`가 사용됩니다. 운영 환경에서는 기본값을 사용하지 말고 DAPMS의 Tool Server API Key와 동일한 별도 Secret을 주입해야 합니다.
각 Pod는 별도 터미널에서 실행합니다.
```powershell
# 영업 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8082'
.\gradlew.bat :dap-was-sal:bootRun
# 고객 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8084'
.\gradlew.bat :dap-was-cus:bootRun
# 상품 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8085'
.\gradlew.bat :dap-was-pro:bootRun
# 시스템 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8086'
.\gradlew.bat :dap-was-sys:bootRun
```
실행 후 SYS Pod 기준 확인 URL은 다음과 같습니다.
```text
http://localhost:8086/mcp/api/v1/tools/local
http://localhost:8086/tool-manifest
http://localhost:8086/swagger-ui/index.html
```
### 주요 환경 변수
| 환경 변수 | 설명 | 기본값 |
|---|---|---|
| `SPRING_PROFILES_ACTIVE` | Spring 활성 프로필 | `local` |
| `PORT` | Pod 수신 포트 | 모듈별 기본 포트 |
| `TOOL_SERVER_API_KEY` | DAPMS가 `X-Tool-Server-API-Key`로 전달할 공통 인증 Key | `tool-server-key` |
| `AXHUB_TOOL_URL` | Manifest의 Tool endpoint 생성에 사용할 Pod 외부 URL | `http://localhost:${server.port}` |
| `AXHUB_GATEWAY_URL` | 프로필 및 Compose 호환용 Gateway URL. 현재 DAPMT의 push 등록에는 사용하지 않음 | `http://localhost:8081` |
| `SPRING_DATA_REDIS_HOST` | Redis 호스트 | `localhost` |
| `SPRING_DATA_REDIS_PORT` | Redis 포트 | `6379` |
| `GLOW_COMMUNICATION_MCI_HOST` | MCI 대상 호스트 | 프로필별 설정 |
| `GLOW_COMMUNICATION_MCI_PORT` | MCI 대상 포트 | 프로필별 설정 |
`mcp.security.api-key`는 단일 DAPMS 공통 Key를, `mcp.security.api-keys``API Key → tenant ID` 형태의 다중 Key를 지원합니다. 둘 중 하나라도 설정되어 있으면 올바른 `X-Tool-Server-API-Key`가 없는 `/rpc/**`, `/mcp/**` 요청은 `401 Unauthorized`가 됩니다. 두 설정이 모두 비어 있을 때만 익명 요청을 허용합니다. 현재 네 업무 Pod의 기본 `application.yml`은 단일 Key를 설정하므로 API Key 없이 Tool을 호출할 수 없습니다.
## Scaffold
공통 라이브러리는 새 Tool과 새 Tool Pod를 만드는 두 개의 Java CLI를 제공합니다. 두 클래스의 `main` 메서드를 IDE에서 실행하거나 필요한 인자를 전달해 실행할 수 있습니다.
| Scaffolder | 역할 | 주요 생성·수정 대상 |
|---|---|---|
| `ToolScaffolder` | 기존 Pod에 Tool 구현 추가 | UseCase, DTO, Converter, Mock 응답, V17 Tool YAML, 연동 설정 |
| `PodScaffolder` | 새 실행 Pod 모듈 추가 | 모듈 디렉터리, `build.gradle`, Dockerfile, Application 클래스, 프로필 설정, `settings.gradle`, `docker-compose.yml` |
`PodScaffolder`의 인자 순서는 다음과 같습니다.
```text
PodScaffolder <module-name> <port> [author] [yyyy.MM.dd]
```
예를 들어 `payment 8099`를 입력하면 `dap-was-payment` 모듈을 생성합니다. 생성되는 `application.yml`에는 다음 계약이 포함됩니다.
```yaml
mcp:
manifest:
bundle-id: dap-was-payment
name-prefix: ""
security:
api-key: ${TOOL_SERVER_API_KEY:tool-server-key}
```
생성되는 Compose 서비스에도 `TOOL_SERVER_API_KEY=${TOOL_SERVER_API_KEY:-tool-server-key}`가 추가됩니다. 생성 후에는 다음 항목을 반드시 확인해야 합니다.
1. `bundle-id`를 DAPMS에 등록할 bundle ID와 일치시킵니다.
2. 운영 환경의 `TOOL_SERVER_API_KEY`를 DAPMS가 전달하는 Key와 동일한 Secret으로 설정합니다.
3. 실제 배포 주소에 맞게 `AXHUB_TOOL_URL`을 설정합니다.
4. MCI·EAI·HTTP 연동 대상과 timeout을 환경별 설정으로 교체합니다.
5. `validateMcpToolNames`, `validateToolSchemaV17`, 전체 테스트를 실행합니다.
## 테스트와 검증
```powershell
# 운영 소스 전체 컴파일
.\gradlew.bat classes
# 전체 테스트
.\gradlew.bat test
# 모듈별 테스트
.\gradlew.bat :dap-was-lib:test
.\gradlew.bat :dap-was-cus:test
.\gradlew.bat :dap-was-sal:test
.\gradlew.bat :dap-was-pro:test
.\gradlew.bat :dap-was-sys:test
# Tool 이름·중복 검사
.\gradlew.bat validateMcpToolNames
# 203개 Tool V17 정의 검사
.\gradlew.bat validateToolSchemaV17
# 검증, 테스트, 패키징
.\gradlew.bat clean build
```
### 현재 검증 상태
2026-08-18 기준 확인 결과입니다.
- 전체 `test`: 성공
- 총 94개 테스트 성공, 실패·오류·건너뜀 0개
- `validateMcpToolNames`: 성공
- `validateToolSchemaV17`: 203개 Tool 성공
- 실행 명령: `.\gradlew.bat test validateMcpToolNames validateToolSchemaV17`
## Docker Compose
`docker-compose.yml`은 DAPMT의 네 업무 Pod만 정의합니다.
| 서비스 | 컨테이너 포트 | 호스트 포트 |
|---|---:|---:|
| `was-sal` | 8082 | 8282 |
| `was-cus` | 8084 | 8284 |
| `was-pro` | 8085 | 8285 |
| `was-sys` | 8086 | 8286 |
모듈 Dockerfile은 사전에 생성된 Boot JAR를 이미지에 복사합니다. 먼저 JAR를 빌드한 뒤 Compose를 실행합니다.
```powershell
.\gradlew.bat :dap-was-sal:bootJar :dap-was-cus:bootJar :dap-was-pro:bootJar :dap-was-sys:bootJar
docker compose up --build
```
Compose 파일의 용도와 현재 주의점은 다음과 같습니다.
| 파일 | 용도 | 현재 소스 기준 주의점 |
|---|---|---|
| `docker-compose.yml` | DAPMT 네 Pod 단독 실행 | `gateway` 서비스가 없지만 push 등록이 제거되어 DAPMT 시작에는 필요하지 않음 |
| `docker-compose.local.yml` | DAPMS와 DAPMT의 로컬 통합 구성 | 두 저장소가 같은 상위 디렉터리에 있는 구조를 가정 |
| `docker-compose.prod.yml` | DAPMS와 DAPMT의 개발 프로필 기반 OCI 구성 | 저장소의 runner 등록 토큰을 운영 Secret으로 분리해야 함 |
`docker-compose.local.yml``docker-compose.prod.yml`의 build context는 각각 `./dap-was-dapms`, `./dap-was-dapmt`입니다. 현재 파일 위치에서 사용할 때는 context 기준을 두 저장소의 상위 디렉터리로 맞춰야 합니다.
```powershell
# DAPMT 저장소 디렉터리에서 실행
docker compose --project-directory .. -f docker-compose.local.yml up --build
```
현재 기존 네 Pod의 Compose 정의에는 `TOOL_SERVER_API_KEY` 환경 변수 전달이 없습니다. 따라서 컨테이너는 애플리케이션 기본값 `tool-server-key`를 사용합니다. 운영 배포 전 각 서비스에 Secret 기반 `TOOL_SERVER_API_KEY` 전달 설정을 추가하고 DAPMS의 Key와 일치시켜야 합니다. DAPMS는 각 Pod의 `AXHUB_TOOL_URL` 또는 배포 URL에 접근해 `/tool-manifest`를 pull할 수 있어야 합니다.
## 보안 및 운영 주의사항
현재 구현을 운영 환경에 노출하기 전에 아래 항목을 반드시 점검해야 합니다.
- API Key 인터셉터는 `/rpc/**`, `/mcp/**`에 적용됩니다. 따라서 `/mcp`, `/mcp/{toolName}`, `/mcp/api/v1/tools/local`은 인증 대상입니다.
- `/tool-manifest`는 위 인터셉터 경로 밖에 있어 현재 API Key 인증 대상이 아닙니다. 내부망·Ingress 정책 또는 별도 인증이 필요한지 운영 기준을 확인해야 합니다.
- 네 업무 Pod의 기본 Key는 모두 `tool-server-key`입니다. 운영에서는 반드시 별도 Secret으로 교체하고 DAPMS의 `X-Tool-Server-API-Key` 값과 일치시켜야 합니다.
- 설정된 단일 Key와 다중 Key가 모두 없을 때만 익명 요청이 허용됩니다.
- `mcp.security.tenant-domains`는 설정 객체에 바인딩되지만 Tool별 인가에 사용되지 않습니다.
- `requiresApproval`은 메타데이터에만 기록되며 실행 차단이나 승인 확인 로직은 없습니다.
- 입력·출력 Schema 처리 자체에서 예외가 발생하면 현재 실행 서비스는 로그를 남기고 검증을 건너뜁니다.
- CORS는 모든 Origin을 허용하면서 credential도 허용하도록 설정되어 있습니다. 운영 Origin을 명시적으로 제한해야 합니다.
- `docker-compose.prod.yml`에 runner 등록 토큰이 평문으로 포함되어 있습니다. 사용 중인 토큰은 폐기·재발급하고 배포 Secret으로 이전해야 합니다.
- Tool 요청과 연동 오류 로그에 개인정보나 인증정보가 포함되지 않도록 DTO와 로그 마스킹 정책을 검토해야 합니다.
## 주요 소스 위치
| 주제 | 위치 |
| 항목 | 내용 |
|---|---|
| 공통 빌드 및 검증 작업 | `build.gradle` |
| REST Tool 실행 API | `dap-was-lib/src/main/java/io/shinhanlife/dap/mcc/presentation/BusinessToolController.java` |
| 요청 헤더 캡처·전달 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilter.java`, `McpRequestHeaderContext.java` |
| Tool 실행 서비스 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpToolExecutionService.java` |
| JSON Schema 2020-12 검증 설정 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/config/ToolSchemaConfiguration.java` |
| 실행 메서드 Registry | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpToolMethodRegistry.java` |
| MCP SDK 서버 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMcpServerConfiguration.java` |
| MCP Tool 동기화 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java` |
| Tool 스캔 및 메타데이터 생성 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java` |
| YAML Tool 정의 로딩 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/metadata/ToolDefinitionRepository.java` |
| V17 정의 검증 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/metadata/ToolDefinitionValidator.java` |
| Manifest 생성 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/manifest/ToolManifestService.java` |
| API Key 인터셉터 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/security/ApiKeyInterceptor.java` |
| Tool·Pod 스캐폴딩 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/util/ToolScaffolder.java`, `PodScaffolder.java` |
| **서비스명 (모듈)** | `dat-was-sys` (`dat-was-datsy`) |
| **서버 포트** | **8086** (기본) |
| **MCP 엔드포인트** | `http://localhost:8086/mcp`, `http://localhost:8086/mcp/message` |
| **Swagger UI** | `http://localhost:8086/swagger-ui.html` |
| **Bundle ID** | `was-sys` |
| **기반 기술** | Java 21, Spring Boot 3.5.11, MCP Java SDK 2.0.0 |
| **공통 의존성** | `io.shinhanlife:dat-lib-datmt:0.0.1-SNAPSHOT` (`dat-was-lib`) |
## 개발 시 권장 확인 순서
---
## 2. 제공 MCP 도구 (Tools) 목록
### ① IAM (Identity & Access Management / 조직)
- **`AccountInquiryUseCase`**: 사번 또는 계정 ID를 통한 사용자/임직원 기본 정보 조회
- **`AuthenticationInquiryUseCase`**: 계정의 2차 인증 상태, 계정 잠김 여부 등 인증 상태 확인
- **`AuthorizationInquiryUseCase`**: 사용자가 보유한 시스템 권한 그룹 및 리소스 접근 인가 현황 조회
- **`SystemStatusUseCase`**: 신한라이프 주요 IT 서비스 및 연계 채널의 실시간 가동 상태 점검
- **`TeamContactUseCase`**: 특정 업무/시스템별 담당 부서, 담당자 및 비상 연락처 조회
### ② PCT (Process & Change Management / 운영)
- **`MaintenanceInquiryUseCase`**: 예정된 시스템 정기 점검, 서버 패치 및 서비스 중단 일정 조회
- **`ReleaseInquiryUseCase`**: 최근 배포된 시스템 기능 개선 및 릴리즈 이력 정보 조회
- **`SystemNoticeUseCase`**: 전사 시스템 공지사항 및 긴급 장애 공지 내역 조회
---
## 3. 공통 라이브러리 연동 (Composite Build)
본 저장소는 상위 워크스페이스의 `../dat-lib-datmt` 공통 라이브러리를 로컬 복합 빌드(Composite Build)로 직접 참조합니다.
```text
workspace/
├── dat-lib-datmt/ # 공통 라이브러리 (:dat-was-lib)
└── dat-was-datsy/ # [현재 저장소] 시스템 도메인 Tool Pod (:dat-was-sys)
```
---
## 4. 빌드 및 실행 가이드
### 컴파일 및 빌드
```powershell
.\gradlew.bat compileJava
```
### 단위 테스트 실행
```powershell
.\gradlew.bat test
```
### 로컬 애플리케이션 실행
```powershell
.\gradlew.bat :dat-was-sys:bootRun
```
*기본 활성화 프로파일: `local` (`application-local.yml` 참조)*
### 도커 컨테이너 빌드 및 로컬 구동
```powershell
docker compose -f docker-compose.local.yml up -d --build
```
1. Tool 메서드와 요청·응답 DTO를 구현합니다.
2. 동일 이름의 V17 YAML 정의를 `tool-definitions` 아래에 추가합니다.
3. `validateMcpToolNames``validateToolSchemaV17`을 실행합니다.
4. 모듈 테스트와 전체 테스트를 실행합니다.
5. 로컬 Pod에서 `/mcp/api/v1/tools/local``/tool-manifest`를 확인합니다.
6. DAPMS의 bundle ID, Pod Manifest URL, Tool Server API Key가 DAPMT 설정과 일치하는지 확인합니다.
7. REST와 MCP 양쪽에서 동일한 Tool 결과·요청 헤더 전달·오류 계약을 확인합니다.

View File

@@ -1,113 +1,178 @@
// 루트 Gradle 설정: 모든 Gateway/Tool Pod 모듈이 공유하는 빌드 기준을 정의합니다.
plugins {
// Java 컴파일, 테스트, JAR 생성 기능을 제공합니다.
id 'java'
// 하위 실행 모듈에서 bootRun/bootJar를 사용하기 위한 Spring Boot 플러그인입니다.
// 루트 프로젝트에는 적용하지 않으므로 apply false를 사용합니다.
id 'org.springframework.boot' version '3.5.11' apply false
// Spring Boot / Spring AI BOM에 정의된 라이브러리 버전을 일관되게 적용합니다.
id 'io.spring.dependency-management' version '1.1.6' apply false
id 'org.springframework.boot' version '3.5.11'
id 'io.spring.dependency-management' version '1.1.7'
}
// 모든 모듈이 공유하는 Maven 식별자입니다.
// ============================================================================
// 전체 프로젝트 공통 Maven 좌표
// ============================================================================
allprojects {
// 모든 모듈이 공유하는 Maven Group ID입니다.
group = 'io.shinhanlife'
// 모든 모듈이 공유하는 프로젝트 버전입니다.
version = '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
}
// dap-gateway, dap-was-lib, dap-was-oth, dap-was-sms에 공통 적용합니다.
subprojects {
// 모든 하위 모듈에서 Java Plugin을 사용합니다.
apply plugin: 'java'
// Spring Boot BOM 기반 의존성 버전 관리를 위해 적용합니다.
apply plugin: 'io.spring.dependency-management'
java {
// 프로젝트 표준 Java 버전입니다.
sourceCompatibility = '21'
}
repositories {
// 현재 공개 정식 라이브러리 저장소입니다.
// 폐쇄망 적용 시 사내 Nexus Proxy URL로 교체합니다.
mavenCentral()
}
dependencyManagement {
imports {
// Spring Boot 3.5.11과 호환되는 Spring/Jackson/Tomcat 등의 버전을 관리합니다.
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
// Boot 3.5.11과 호환되는 Spring AI 계층은 1.1.8로 유지합니다.
mavenBom 'org.springframework.ai:spring-ai-bom:1.1.8'
// MCP Java SDK만 2.0.0으로 올립니다. Spring AI 2.x 전체 BOM은 Boot 4 기반이므로 사용하지 않습니다.
mavenBom 'io.modelcontextprotocol.sdk:mcp-bom:2.0.0'
// MCP SDK 2.0의 Jackson 2 전송 모듈이 요구하는 호환 버전입니다.
mavenBom 'com.fasterxml.jackson:jackson-bom:2.20.1'
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
// [로컬 개발 순서]
// 1. ../dat-lib-datmt에서 .\gradlew.bat :dat-was-lib:publishToMavenLocal 실행
// 2. 위 명령이 ~/.m2/repository/io/shinhanlife/dat-lib-datmt에 JAR/POM을 등록
// 3. 아래 mavenLocal()이 등록된 JAR을 찾아 implementation 의존성을 해석
//
// [신한라이프 이관]
// mavenLocal() 대신 사내 Nexus Maven repository를 추가합니다.
// implementation 좌표는 그대로 유지합니다.
mavenLocal()
// --------------------------------------------------------------------
// 외부 개발 환경
// --------------------------------------------------------------------
//
// 현재 인터넷이 가능한 환경에서는 Maven Central을 사용합니다.
//
// 신한라이프 폐쇄망 반입 시 아래 mavenCentral()은 제거하고
// 사내 Nexus Repository URL로 교체해야 합니다.
//
// 예:
//
// maven {
// url = uri('https://내부-Nexus/repository/maven-public/')
// }
//
// Nexus 인증이 필요한 경우에는 credentials 설정도 추가해야 합니다.
//
// credentials {
// username = findProperty('nexusUsername') ?: System.getenv('NEXUS_USERNAME')
// password = findProperty('nexusPassword') ?: System.getenv('NEXUS_PASSWORD')
// }
//
// 계정/비밀번호를 build.gradle에 직접 작성하면 안 됩니다.
// --------------------------------------------------------------------
mavenCentral()
}
// ========================================================================
// Dependency Version Management
// ========================================================================
dependencyManagement {
imports {
// Spring Boot 3.5.11이 검증한
// Spring Framework / Jackson / Tomcat / Logback /
// JUnit 등 주요 라이브러리 버전을 공통 관리합니다.
// 하위 모듈에서는 Spring Boot가 관리하는 라이브러리라면
// 가급적 개별 버전을 직접 지정하지 않고 사용합니다.
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
// MCP SDK 버전 관리
mavenBom 'io.modelcontextprotocol.sdk:mcp-bom:2.0.0'
}
}
// ========================================================================
// Common Dependencies
// ========================================================================
dependencies {
// Lombok은 컴파일 시 getter/builder 등 반복 코드를 생성하며 실행 JAR에는 포함하지 않습니다.
compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
testCompileOnly 'org.projectlombok:lombok:1.18.32'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'
// Tool DTO와 MCI 요청/응답 객체 간 Converter 구현체를 컴파일 시 자동 생성합니다.
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
// ====================================================================
// Lombok
// ====================================================================
// 모든 모듈의 JUnit 5 기반 테스트 공통 의존성입니다.
// Lombok은 컴파일 시 Getter / Setter / Builder 등의
// 반복 코드를 생성합니다.
//
// compileOnly이므로 Runtime JAR에는 포함되지 않습니다.
compileOnly 'org.projectlombok:lombok'
// Lombok Annotation Processor입니다.
annotationProcessor 'org.projectlombok:lombok'
// 테스트 코드에서도 Lombok Annotation을 사용할 수 있도록 합니다.
testCompileOnly 'org.projectlombok:lombok'
// 테스트 코드용 Lombok Annotation Processor입니다.
testAnnotationProcessor 'org.projectlombok:lombok'
// ====================================================================
// MapStruct
// ====================================================================
// Tool DTO와
// MCI 요청/응답 DTO 사이의 Converter 구현체를
// 컴파일 시 자동 생성하기 위해 사용합니다.
implementation 'org.mapstruct:mapstruct:1.6.3'
// MapStruct Converter 구현 클래스를 생성하는
// Annotation Processor입니다.
annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3'
// ====================================================================
// Test
// ====================================================================
// Spring Boot Test / JUnit 5 / Mockito / AssertJ 등
// 공통 테스트 환경을 제공합니다.
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Gradle / IDE 환경에서 JUnit Platform 기반 테스트 실행을 지원합니다.
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.withType(JavaCompile) {
// 리플렉션/MCP Schema 생성 시 메서드 파라미터명을 사용할 수 있도록 보존합니다.
// ========================================================================
// Java Compile Options
// ========================================================================
tasks.withType(JavaCompile).configureEach {
// Reflection 및 MCP Schema 생성 시
// Java 메서드의 실제 파라미터명을 사용할 수 있도록
// 컴파일 결과에 파라미터 이름을 보존합니다.
options.compilerArgs << '-parameters'
// MapStruct 구현체를 Spring Bean으로 생성해 생성자 주입으로 사용할 수 있게 합니다.
// MapStruct가 생성하는 Converter 구현 클래스를
// Spring Bean(@Component)으로 생성합니다.
//
// 이를 통해 생성자 주입 등의 방식으로 사용할 수 있습니다.
options.compilerArgs << '-Amapstruct.defaultComponentModel=spring'
}
tasks.withType(Test) {
// JUnit 5 테스트 플랫폼을 사용합니다.
// ========================================================================
// Test Configuration
// ========================================================================
tasks.withType(Test).configureEach {
// 모든 하위 모듈에서 JUnit 5 Platform을 사용합니다.
useJUnitPlatform()
}
}
// Tool 이름 중복 검사 프로그램이 포함된 공통 라이브러리 모듈입니다.
def toolCoreProject = project(':dap-was-lib')
// 전체 Tool Pod의 @McpTool(name) 중복을 배포 산출물 생성 전에 차단합니다.
tasks.register('validateMcpToolNames', JavaExec) {
group = 'verification'
description = 'Checks duplicate @McpTool names across all Tool modules before packaging.'
// 검사 Runner를 실행하기 전에 dap-was-lib 클래스를 먼저 컴파일합니다.
dependsOn toolCoreProject.tasks.named('classes')
classpath = toolCoreProject.sourceSets.main.runtimeClasspath
mainClass.set('io.shinhanlife.dap.lib.validation.McpToolNameValidationRunner')
args rootProject.projectDir.absolutePath
}
tasks.register('validateToolSchemaV17', JavaExec) {
group = 'verification'
description = 'Validates BC-DAB-STD-003 V17 definitions for every @McpTool.'
dependsOn toolCoreProject.tasks.named('classes')
classpath = toolCoreProject.sourceSets.main.runtimeClasspath
mainClass.set('io.shinhanlife.dap.lib.validation.ToolSchemaV17ValidationRunner')
args rootProject.projectDir.absolutePath
}
subprojects {
// 배포용 Spring Boot JAR 생성 전에 Tool 이름 중복 검증을 강제합니다.
tasks.matching { it.name == 'bootJar' }.configureEach {
dependsOn rootProject.tasks.named('validateMcpToolNames')
dependsOn rootProject.tasks.named('validateToolSchemaV17')
}
}

View File

@@ -1,8 +0,0 @@
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN apk add --no-cache tzdata
ENV TZ=Asia/Seoul
COPY dap-was-cus/build/libs/*-SNAPSHOT.jar app.jar
EXPOSE 8084
ENTRYPOINT ["java", "-jar", "app.jar"]

View File

@@ -1,10 +0,0 @@
plugins {
// OTH Tool Pod를 독립 실행 가능한 Spring Boot JAR로 생성합니다.
id 'org.springframework.boot'
}
dependencies {
// MCP Server, Tool 공통 처리, MCI/EAI 연동 기반은 dap-was-lib에서 상속합니다.
implementation project(':dap-was-lib')
implementation 'org.apache.poi:poi-ooxml:5.3.0'
}

View File

@@ -1,34 +0,0 @@
package io.shinhanlife.dap.mcc.biz.crm.dto;
import lombok.Data;
import org.springaicommunity.mcp.annotation.McpToolParam;
@Data
public class CrmToolRequest {
@McpToolParam(description = "업무 대상 식별자", required = false)
private String subjectId;
@McpToolParam(description = "고객 식별자", required = false)
private String customerId;
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
private String content;
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
private String value;
@McpToolParam(description = "담당자 식별자", required = false)
private String assigneeId;
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
private String startDate;
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
private String endDate;
@McpToolParam(description = "페이지 번호", required = false)
private Integer page;
@McpToolParam(description = "페이지 크기", required = false)
private Integer size;
}

View File

@@ -1,15 +0,0 @@
package io.shinhanlife.dap.mcc.biz.crm.dto;
import java.util.List;
import lombok.Data;
@Data
public class CrmToolResponse {
private String toolName;
private String category;
private String referenceId;
private String status;
private String summary;
private String processedAt;
private List<String> details;
}

View File

@@ -1,60 +0,0 @@
package io.shinhanlife.dap.mcc.biz.crm.usecase;
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolRequest;
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolResponse;
import org.springaicommunity.mcp.annotation.McpTool;
public interface CrmToolUseCase {
@McpTool(name = "crm_customer_search", title = "고객 통합 조회", description = "고객 통합 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_SEARCH")
CrmToolResponse searchCustomers(CrmToolRequest request);
@McpTool(name = "crm_customer_detail", title = "고객 상세 정보 조회", description = "고객 상세 정보 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_DETAIL")
CrmToolResponse getCustomerDetail(CrmToolRequest request);
@McpTool(name = "crm_customer_create", title = "고객 정보 등록", description = "고객 정보 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_CREATE")
CrmToolResponse createCustomer(CrmToolRequest request);
@McpTool(name = "crm_customer_update", title = "고객 정보 수정", description = "고객 정보 수정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_UPDATE")
CrmToolResponse updateCustomer(CrmToolRequest request);
@McpTool(name = "crm_customer_duplicate_check", title = "고객 중복 여부 확인", description = "고객 중복 여부 확인 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_DUPLICATE_CHECK")
CrmToolResponse checkDuplicateCustomer(CrmToolRequest request);
@McpTool(name = "crm_consultation_history", title = "고객 상담 이력 조회", description = "고객 상담 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSULTATION_HISTORY")
CrmToolResponse getConsultationHistory(CrmToolRequest request);
@McpTool(name = "crm_consultation_register", title = "고객 상담 이력 등록", description = "고객 상담 이력 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSULTATION_REGISTER")
CrmToolResponse registerConsultation(CrmToolRequest request);
@McpTool(name = "crm_contact_history", title = "고객 접촉 이력 조회", description = "고객 접촉 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONTACT_HISTORY")
CrmToolResponse getContactHistory(CrmToolRequest request);
@McpTool(name = "crm_contact_register", title = "고객 접촉 이력 등록", description = "고객 접촉 이력 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONTACT_REGISTER")
CrmToolResponse registerContact(CrmToolRequest request);
@McpTool(name = "crm_grade_detail", title = "고객 등급 조회", description = "고객 등급 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_GRADE_DETAIL")
CrmToolResponse getCustomerGrade(CrmToolRequest request);
@McpTool(name = "crm_grade_change", title = "고객 등급 변경", description = "고객 등급 변경 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_GRADE_CHANGE")
CrmToolResponse changeCustomerGrade(CrmToolRequest request);
@McpTool(name = "crm_segment_detail", title = "고객 세그먼트 조회", description = "고객 세그먼트 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_SEGMENT_DETAIL")
CrmToolResponse getCustomerSegment(CrmToolRequest request);
@McpTool(name = "crm_tag_manage", title = "고객 태그 관리", description = "고객 태그 관리 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_TAG_MANAGE")
CrmToolResponse manageCustomerTags(CrmToolRequest request);
@McpTool(name = "crm_consent_detail", title = "고객 동의 정보 조회", description = "고객 동의 정보 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSENT_DETAIL")
CrmToolResponse getCustomerConsent(CrmToolRequest request);
@McpTool(name = "crm_consent_change", title = "고객 동의 정보 변경", description = "고객 동의 정보 변경 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSENT_CHANGE")
CrmToolResponse changeCustomerConsent(CrmToolRequest request);
@McpTool(name = "crm_owner_assign", title = "고객 담당자 배정", description = "고객 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_OWNER_ASSIGN")
CrmToolResponse assignCustomerOwner(CrmToolRequest request);
@McpTool(name = "crm_activity_status", title = "고객 활동 현황 조회", description = "고객 활동 현황 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_ACTIVITY_STATUS")
CrmToolResponse getCustomerActivityStatus(CrmToolRequest request);
}

View File

@@ -1,95 +0,0 @@
package io.shinhanlife.dap.mcc.biz.crm.usecase.impl;
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolRequest;
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolResponse;
import io.shinhanlife.dap.mcc.biz.crm.usecase.CrmToolUseCase;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class CrmToolUseCaseImpl implements CrmToolUseCase {
@Override
public CrmToolResponse searchCustomers(CrmToolRequest request) {
return mockResponse(request, "crm_customer_search", "고객 통합 조회");
}
@Override
public CrmToolResponse getCustomerDetail(CrmToolRequest request) {
return mockResponse(request, "crm_customer_detail", "고객 상세 정보 조회");
}
@Override
public CrmToolResponse createCustomer(CrmToolRequest request) {
return mockResponse(request, "crm_customer_create", "고객 정보 등록");
}
@Override
public CrmToolResponse updateCustomer(CrmToolRequest request) {
return mockResponse(request, "crm_customer_update", "고객 정보 수정");
}
@Override
public CrmToolResponse checkDuplicateCustomer(CrmToolRequest request) {
return mockResponse(request, "crm_customer_duplicate_check", "고객 중복 여부 확인");
}
@Override
public CrmToolResponse getConsultationHistory(CrmToolRequest request) {
return mockResponse(request, "crm_consultation_history", "고객 상담 이력 조회");
}
@Override
public CrmToolResponse registerConsultation(CrmToolRequest request) {
return mockResponse(request, "crm_consultation_register", "고객 상담 이력 등록");
}
@Override
public CrmToolResponse getContactHistory(CrmToolRequest request) {
return mockResponse(request, "crm_contact_history", "고객 접촉 이력 조회");
}
@Override
public CrmToolResponse registerContact(CrmToolRequest request) {
return mockResponse(request, "crm_contact_register", "고객 접촉 이력 등록");
}
@Override
public CrmToolResponse getCustomerGrade(CrmToolRequest request) {
return mockResponse(request, "crm_grade_detail", "고객 등급 조회");
}
@Override
public CrmToolResponse changeCustomerGrade(CrmToolRequest request) {
return mockResponse(request, "crm_grade_change", "고객 등급 변경");
}
@Override
public CrmToolResponse getCustomerSegment(CrmToolRequest request) {
return mockResponse(request, "crm_segment_detail", "고객 세그먼트 조회");
}
@Override
public CrmToolResponse manageCustomerTags(CrmToolRequest request) {
return mockResponse(request, "crm_tag_manage", "고객 태그 관리");
}
@Override
public CrmToolResponse getCustomerConsent(CrmToolRequest request) {
return mockResponse(request, "crm_consent_detail", "고객 동의 정보 조회");
}
@Override
public CrmToolResponse changeCustomerConsent(CrmToolRequest request) {
return mockResponse(request, "crm_consent_change", "고객 동의 정보 변경");
}
@Override
public CrmToolResponse assignCustomerOwner(CrmToolRequest request) {
return mockResponse(request, "crm_owner_assign", "고객 담당자 배정");
}
@Override
public CrmToolResponse getCustomerActivityStatus(CrmToolRequest request) {
return mockResponse(request, "crm_activity_status", "고객 활동 현황 조회");
}
private CrmToolResponse mockResponse(CrmToolRequest request, String toolName, String title) {
CrmToolResponse response = new CrmToolResponse();
response.setToolName(toolName);
response.setCategory("CRM");
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "CRM-000001");
response.setStatus("정상");
response.setSummary(title + " 처리 결과");
response.setProcessedAt(LocalDateTime.now().toString());
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
return response;
}
private boolean hasText(String value) {
return value != null && !value.isBlank();
}
}

View File

@@ -1,34 +0,0 @@
package io.shinhanlife.dap.mcc.biz.voc.dto;
import lombok.Data;
import org.springaicommunity.mcp.annotation.McpToolParam;
@Data
public class VocToolRequest {
@McpToolParam(description = "업무 대상 식별자", required = false)
private String subjectId;
@McpToolParam(description = "고객 식별자", required = false)
private String customerId;
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
private String content;
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
private String value;
@McpToolParam(description = "담당자 식별자", required = false)
private String assigneeId;
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
private String startDate;
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
private String endDate;
@McpToolParam(description = "페이지 번호", required = false)
private Integer page;
@McpToolParam(description = "페이지 크기", required = false)
private Integer size;
}

View File

@@ -1,15 +0,0 @@
package io.shinhanlife.dap.mcc.biz.voc.dto;
import java.util.List;
import lombok.Data;
@Data
public class VocToolResponse {
private String toolName;
private String category;
private String referenceId;
private String status;
private String summary;
private String processedAt;
private List<String> details;
}

View File

@@ -1,60 +0,0 @@
package io.shinhanlife.dap.mcc.biz.voc.usecase;
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolRequest;
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolResponse;
import org.springaicommunity.mcp.annotation.McpTool;
public interface VocToolUseCase {
@McpTool(name = "voc_register", title = "VOC 접수 등록", description = "VOC 접수 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_REGISTER")
VocToolResponse registerVoc(VocToolRequest request);
@McpTool(name = "voc_detail", title = "VOC 상세 조회", description = "VOC 상세 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_DETAIL")
VocToolResponse getVocDetail(VocToolRequest request);
@McpTool(name = "voc_search", title = "VOC 목록 검색", description = "VOC 목록 검색 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_SEARCH")
VocToolResponse searchVocs(VocToolRequest request);
@McpTool(name = "voc_update", title = "VOC 내용 수정", description = "VOC 내용 수정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_UPDATE")
VocToolResponse updateVoc(VocToolRequest request);
@McpTool(name = "voc_assign", title = "VOC 담당자 배정", description = "VOC 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_ASSIGN")
VocToolResponse assignVocOwner(VocToolRequest request);
@McpTool(name = "voc_change_status", title = "VOC 처리 상태 변경", description = "VOC 처리 상태 변경 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_CHANGE_STATUS")
VocToolResponse changeVocStatus(VocToolRequest request);
@McpTool(name = "voc_register_result", title = "VOC 처리 결과 등록", description = "VOC 처리 결과 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_REGISTER_RESULT")
VocToolResponse registerVocResult(VocToolRequest request);
@McpTool(name = "voc_send_reply", title = "VOC 답변 발송", description = "VOC 답변 발송 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_SEND_REPLY")
VocToolResponse sendVocReply(VocToolRequest request);
@McpTool(name = "voc_transfer", title = "VOC 이관 처리", description = "VOC 이관 처리 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_TRANSFER")
VocToolResponse transferVoc(VocToolRequest request);
@McpTool(name = "voc_set_priority", title = "VOC 우선순위 설정", description = "VOC 우선순위 설정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_SET_PRIORITY")
VocToolResponse setVocPriority(VocToolRequest request);
@McpTool(name = "voc_classify_type", title = "VOC 유형 분류", description = "VOC 유형 분류 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_CLASSIFY_TYPE")
VocToolResponse classifyVocType(VocToolRequest request);
@McpTool(name = "voc_attachments", title = "VOC 첨부파일 조회", description = "VOC 첨부파일 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_ATTACHMENTS")
VocToolResponse getVocAttachments(VocToolRequest request);
@McpTool(name = "voc_customer_history", title = "고객별 VOC 이력 조회", description = "고객별 VOC 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_CUSTOMER_HISTORY")
VocToolResponse getCustomerVocHistory(VocToolRequest request);
@McpTool(name = "voc_detect_duplicate", title = "중복 VOC 탐지", description = "중복 VOC 탐지 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_DETECT_DUPLICATE")
VocToolResponse detectDuplicateVoc(VocToolRequest request);
@McpTool(name = "voc_urgent_list", title = "긴급 VOC 목록 조회", description = "긴급 VOC 목록 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_URGENT_LIST")
VocToolResponse getUrgentVocs(VocToolRequest request);
@McpTool(name = "voc_extend_due_date", title = "VOC 처리 기한 연장", description = "VOC 처리 기한 연장 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_EXTEND_DUE_DATE")
VocToolResponse extendVocDueDate(VocToolRequest request);
@McpTool(name = "voc_statistics", title = "VOC 통계 조회", description = "VOC 통계 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_STATISTICS")
VocToolResponse getVocStatistics(VocToolRequest request);
}

View File

@@ -1,95 +0,0 @@
package io.shinhanlife.dap.mcc.biz.voc.usecase.impl;
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolRequest;
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolResponse;
import io.shinhanlife.dap.mcc.biz.voc.usecase.VocToolUseCase;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class VocToolUseCaseImpl implements VocToolUseCase {
@Override
public VocToolResponse registerVoc(VocToolRequest request) {
return mockResponse(request, "voc_register", "VOC 접수 등록");
}
@Override
public VocToolResponse getVocDetail(VocToolRequest request) {
return mockResponse(request, "voc_detail", "VOC 상세 조회");
}
@Override
public VocToolResponse searchVocs(VocToolRequest request) {
return mockResponse(request, "voc_search", "VOC 목록 검색");
}
@Override
public VocToolResponse updateVoc(VocToolRequest request) {
return mockResponse(request, "voc_update", "VOC 내용 수정");
}
@Override
public VocToolResponse assignVocOwner(VocToolRequest request) {
return mockResponse(request, "voc_assign", "VOC 담당자 배정");
}
@Override
public VocToolResponse changeVocStatus(VocToolRequest request) {
return mockResponse(request, "voc_change_status", "VOC 처리 상태 변경");
}
@Override
public VocToolResponse registerVocResult(VocToolRequest request) {
return mockResponse(request, "voc_register_result", "VOC 처리 결과 등록");
}
@Override
public VocToolResponse sendVocReply(VocToolRequest request) {
return mockResponse(request, "voc_send_reply", "VOC 답변 발송");
}
@Override
public VocToolResponse transferVoc(VocToolRequest request) {
return mockResponse(request, "voc_transfer", "VOC 이관 처리");
}
@Override
public VocToolResponse setVocPriority(VocToolRequest request) {
return mockResponse(request, "voc_set_priority", "VOC 우선순위 설정");
}
@Override
public VocToolResponse classifyVocType(VocToolRequest request) {
return mockResponse(request, "voc_classify_type", "VOC 유형 분류");
}
@Override
public VocToolResponse getVocAttachments(VocToolRequest request) {
return mockResponse(request, "voc_attachments", "VOC 첨부파일 조회");
}
@Override
public VocToolResponse getCustomerVocHistory(VocToolRequest request) {
return mockResponse(request, "voc_customer_history", "고객별 VOC 이력 조회");
}
@Override
public VocToolResponse detectDuplicateVoc(VocToolRequest request) {
return mockResponse(request, "voc_detect_duplicate", "중복 VOC 탐지");
}
@Override
public VocToolResponse getUrgentVocs(VocToolRequest request) {
return mockResponse(request, "voc_urgent_list", "긴급 VOC 목록 조회");
}
@Override
public VocToolResponse extendVocDueDate(VocToolRequest request) {
return mockResponse(request, "voc_extend_due_date", "VOC 처리 기한 연장");
}
@Override
public VocToolResponse getVocStatistics(VocToolRequest request) {
return mockResponse(request, "voc_statistics", "VOC 통계 조회");
}
private VocToolResponse mockResponse(VocToolRequest request, String toolName, String title) {
VocToolResponse response = new VocToolResponse();
response.setToolName(toolName);
response.setCategory("VOC");
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "VOC-000001");
response.setStatus("정상");
response.setSummary(title + " 처리 결과");
response.setProcessedAt(LocalDateTime.now().toString());
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
return response;
}
private boolean hasText(String value) {
return value != null && !value.isBlank();
}
}

View File

@@ -1,34 +0,0 @@
package io.shinhanlife.dap.mcc.biz.wcm.dto;
import lombok.Data;
import org.springaicommunity.mcp.annotation.McpToolParam;
@Data
public class WcmToolRequest {
@McpToolParam(description = "업무 대상 식별자", required = false)
private String subjectId;
@McpToolParam(description = "고객 식별자", required = false)
private String customerId;
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
private String content;
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
private String value;
@McpToolParam(description = "담당자 식별자", required = false)
private String assigneeId;
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
private String startDate;
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
private String endDate;
@McpToolParam(description = "페이지 번호", required = false)
private Integer page;
@McpToolParam(description = "페이지 크기", required = false)
private Integer size;
}

View File

@@ -1,15 +0,0 @@
package io.shinhanlife.dap.mcc.biz.wcm.dto;
import java.util.List;
import lombok.Data;
@Data
public class WcmToolResponse {
private String toolName;
private String category;
private String referenceId;
private String status;
private String summary;
private String processedAt;
private List<String> details;
}

View File

@@ -1,60 +0,0 @@
package io.shinhanlife.dap.mcc.biz.wcm.usecase;
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolRequest;
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolResponse;
import org.springaicommunity.mcp.annotation.McpTool;
public interface WcmToolUseCase {
@McpTool(name = "wcm_content_list", title = "웹 콘텐츠 목록 조회", description = "웹 콘텐츠 목록 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_LIST")
WcmToolResponse getContentList(WcmToolRequest request);
@McpTool(name = "wcm_content_detail", title = "웹 콘텐츠 상세 조회", description = "웹 콘텐츠 상세 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_DETAIL")
WcmToolResponse getContentDetail(WcmToolRequest request);
@McpTool(name = "wcm_content_create", title = "웹 콘텐츠 등록", description = "웹 콘텐츠 등록 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_CREATE")
WcmToolResponse createContent(WcmToolRequest request);
@McpTool(name = "wcm_content_update", title = "웹 콘텐츠 수정", description = "웹 콘텐츠 수정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_UPDATE")
WcmToolResponse updateContent(WcmToolRequest request);
@McpTool(name = "wcm_content_delete", title = "웹 콘텐츠 삭제", description = "웹 콘텐츠 삭제 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_DELETE")
WcmToolResponse deleteContent(WcmToolRequest request);
@McpTool(name = "wcm_content_copy", title = "웹 콘텐츠 복사", description = "웹 콘텐츠 복사 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_COPY")
WcmToolResponse copyContent(WcmToolRequest request);
@McpTool(name = "wcm_content_preview", title = "웹 콘텐츠 미리보기", description = "웹 콘텐츠 미리보기 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_PREVIEW")
WcmToolResponse previewContent(WcmToolRequest request);
@McpTool(name = "wcm_content_publish", title = "웹 콘텐츠 게시", description = "웹 콘텐츠 게시 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_PUBLISH")
WcmToolResponse publishContent(WcmToolRequest request);
@McpTool(name = "wcm_content_unpublish", title = "웹 콘텐츠 게시 중지", description = "웹 콘텐츠 게시 중지 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_UNPUBLISH")
WcmToolResponse unpublishContent(WcmToolRequest request);
@McpTool(name = "wcm_content_schedule_publish", title = "웹 콘텐츠 예약 게시", description = "웹 콘텐츠 예약 게시 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_SCHEDULE_PUBLISH")
WcmToolResponse scheduleContentPublish(WcmToolRequest request);
@McpTool(name = "wcm_content_request_approval", title = "웹 콘텐츠 승인 요청", description = "웹 콘텐츠 승인 요청 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_REQUEST_APPROVAL")
WcmToolResponse requestContentApproval(WcmToolRequest request);
@McpTool(name = "wcm_content_review_approval", title = "웹 콘텐츠 승인·반려", description = "웹 콘텐츠 승인·반려 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_REVIEW_APPROVAL")
WcmToolResponse reviewContentApproval(WcmToolRequest request);
@McpTool(name = "wcm_content_version_history", title = "웹 콘텐츠 버전 이력 조회", description = "웹 콘텐츠 버전 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_VERSION_HISTORY")
WcmToolResponse getContentVersionHistory(WcmToolRequest request);
@McpTool(name = "wcm_content_restore_version", title = "웹 콘텐츠 이전 버전 복원", description = "웹 콘텐츠 이전 버전 복원 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_RESTORE_VERSION")
WcmToolResponse restoreContentVersion(WcmToolRequest request);
@McpTool(name = "wcm_metadata_detail", title = "콘텐츠 메타데이터 조회", description = "콘텐츠 메타데이터 조회 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_METADATA_DETAIL")
WcmToolResponse getContentMetadata(WcmToolRequest request);
@McpTool(name = "wcm_metadata_upsert", title = "콘텐츠 메타데이터 등록·수정", description = "콘텐츠 메타데이터 등록·수정 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_METADATA_UPSERT")
WcmToolResponse upsertContentMetadata(WcmToolRequest request);
@McpTool(name = "wcm_taxonomy_manage", title = "콘텐츠 카테고리·태그 관리", description = "콘텐츠 카테고리·태그 관리 기능을 안전한 모의 데이터로 제공합니다.")
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_TAXONOMY_MANAGE")
WcmToolResponse manageContentTaxonomy(WcmToolRequest request);
}

View File

@@ -1,95 +0,0 @@
package io.shinhanlife.dap.mcc.biz.wcm.usecase.impl;
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolRequest;
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolResponse;
import io.shinhanlife.dap.mcc.biz.wcm.usecase.WcmToolUseCase;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class WcmToolUseCaseImpl implements WcmToolUseCase {
@Override
public WcmToolResponse getContentList(WcmToolRequest request) {
return mockResponse(request, "wcm_content_list", "웹 콘텐츠 목록 조회");
}
@Override
public WcmToolResponse getContentDetail(WcmToolRequest request) {
return mockResponse(request, "wcm_content_detail", "웹 콘텐츠 상세 조회");
}
@Override
public WcmToolResponse createContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_create", "웹 콘텐츠 등록");
}
@Override
public WcmToolResponse updateContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_update", "웹 콘텐츠 수정");
}
@Override
public WcmToolResponse deleteContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_delete", "웹 콘텐츠 삭제");
}
@Override
public WcmToolResponse copyContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_copy", "웹 콘텐츠 복사");
}
@Override
public WcmToolResponse previewContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_preview", "웹 콘텐츠 미리보기");
}
@Override
public WcmToolResponse publishContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_publish", "웹 콘텐츠 게시");
}
@Override
public WcmToolResponse unpublishContent(WcmToolRequest request) {
return mockResponse(request, "wcm_content_unpublish", "웹 콘텐츠 게시 중지");
}
@Override
public WcmToolResponse scheduleContentPublish(WcmToolRequest request) {
return mockResponse(request, "wcm_content_schedule_publish", "웹 콘텐츠 예약 게시");
}
@Override
public WcmToolResponse requestContentApproval(WcmToolRequest request) {
return mockResponse(request, "wcm_content_request_approval", "웹 콘텐츠 승인 요청");
}
@Override
public WcmToolResponse reviewContentApproval(WcmToolRequest request) {
return mockResponse(request, "wcm_content_review_approval", "웹 콘텐츠 승인·반려");
}
@Override
public WcmToolResponse getContentVersionHistory(WcmToolRequest request) {
return mockResponse(request, "wcm_content_version_history", "웹 콘텐츠 버전 이력 조회");
}
@Override
public WcmToolResponse restoreContentVersion(WcmToolRequest request) {
return mockResponse(request, "wcm_content_restore_version", "웹 콘텐츠 이전 버전 복원");
}
@Override
public WcmToolResponse getContentMetadata(WcmToolRequest request) {
return mockResponse(request, "wcm_metadata_detail", "콘텐츠 메타데이터 조회");
}
@Override
public WcmToolResponse upsertContentMetadata(WcmToolRequest request) {
return mockResponse(request, "wcm_metadata_upsert", "콘텐츠 메타데이터 등록·수정");
}
@Override
public WcmToolResponse manageContentTaxonomy(WcmToolRequest request) {
return mockResponse(request, "wcm_taxonomy_manage", "콘텐츠 카테고리·태그 관리");
}
private WcmToolResponse mockResponse(WcmToolRequest request, String toolName, String title) {
WcmToolResponse response = new WcmToolResponse();
response.setToolName(toolName);
response.setCategory("WCMS");
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "WCMS-000001");
response.setStatus("정상");
response.setSummary(title + " 처리 결과");
response.setProcessedAt(LocalDateTime.now().toString());
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
return response;
}
private boolean hasText(String value) {
return value != null && !value.isBlank();
}
}

View File

@@ -1,33 +0,0 @@
package io.shinhanlife.dap.mcc.cus;
/**
* @package io.shinhanlife.dap.mcc.cus
* @className DapWasCusApplication
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Import;
import io.shinhanlife.dap.lib.mcp.ToolMcpServerConfiguration;
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib"})
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib"})
@EnableCaching
@Import(ToolMcpServerConfiguration.class)
public class DapWasCusApplication {
public static void main(String[] args) {
SpringApplication.run(DapWasCusApplication.class, args);
}
}

View File

@@ -1,15 +0,0 @@
# OCI 클라우드 개발 환경 전용 설정
server:
port: ${PORT:8084}
axhub:
gateway:
url: https://axhubmcp.devjun.net
spring:
config:
activate:
on-profile: dev
import:
- classpath:glow/application-glow.yml
- classpath:glow/application-glow-dev.yml

View File

@@ -1,32 +0,0 @@
# Local 환경 전용 설정 (H2 메모리 DB 등)
spring:
config:
activate:
on-profile: local
import:
- classpath:glow/application-glow.yml
- classpath:glow/application-glow-local.yml
datasource:
url: jdbc:p6spy:h2:mem:testdb;DB_CLOSE_DELAY=-1;
driverClassName: com.p6spy.engine.spy.P6SpyDriver
username: sa
password: password
h2:
console:
enabled: true
mcp:
security:
tenant-domains:
mcp-client-1: CUSTOMER,COMMON
mcp-client-2: ALL
axhub:
gateway:
url: http://localhost:8081
tool:
url: ${AXHUB_TOOL_URL:http://localhost:${server.port}}
sol:
req-detail:
mock-enabled: true

View File

@@ -1,16 +0,0 @@
server:
port: ${PORT:8084}
spring:
config:
activate:
on-profile: prod
import:
- classpath:glow/application-glow.yml
- classpath:glow/application-glow-prod.yml
axhub:
gateway:
url: ${AXHUB_GATEWAY_URL}
tool:
url: ${AXHUB_TOOL_URL}

View File

@@ -1,16 +0,0 @@
server:
port: ${PORT:8084}
spring:
config:
activate:
on-profile: test
import:
- classpath:glow/application-glow.yml
- classpath:glow/application-glow-test.yml
axhub:
gateway:
url: ${AXHUB_GATEWAY_URL}
tool:
url: ${AXHUB_TOOL_URL}

View File

@@ -1,20 +0,0 @@
server:
port: 8084
spring:
application:
name: dap-was-cus
profiles:
active: local
logging:
level:
org.apache.kafka: ERROR
mcp:
namespace: ""
manifest:
bundle-id: was-cus
# Set the AA-assigned prefix before MCP pull activation (for example: cus.).
name-prefix: ""
security:
api-key: ${TOOL_SERVER_API_KEY:tool-server-key}
tenant-domains:
TESTER-DEV: ALL

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 1. 로그 패턴 설정 (MDC traceId 포함) -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
<!-- 2. 콘솔(Console) 출력 설정 (로컬 개발용) -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 3. 파일(File) 출력 설정 (서버 운영용) -->
<!-- Logback에서 시스템 Hostname을 가져오기 위한 설정 -->
<property name="HOSTNAME" value="${HOSTNAME}" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/swlog/dap-was-cus/A01/${HOSTNAME}_A01.log</file> <!-- 현재 로그가 쌓이는 파일 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 매일 자정에 날짜를 붙여서 지난 로그를 분리 저장 -->
<fileNamePattern>/swlog/dap-was-cus/A01/${HOSTNAME}_A01_%d{yyyyMMdd}.%i.log</fileNamePattern>
<!-- 개별 로그 파일 크기를 100MB로 제한하고, 전체 보관 일수는 30일, 총 로그 누적 용량은 1GB로 제한 -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 4. 기본 로깅 레벨 설정 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
<!-- 5. 우리 프로젝트 패키지는 디버그 레벨까지 상세히 보기 -->
<logger name="io.shinhanlife" level="DEBUG" />
</configuration>

View File

@@ -1,4 +0,0 @@
{
"resultCode" : "SUCCESS",
"data" : "[{\"date\":\"2024-01-05\",\"message\":\"안내 내용\"}]"
}

View File

@@ -1,4 +0,0 @@
{
"resultCode" : "SUCCESS",
"claimId" : "CLM20230001"
}

View File

@@ -1,30 +0,0 @@
name: crm_activity_status
display_name: 고객 활동 현황 조회
version: 1.0.0
category_key: crm
description:
function: 고객 활동 현황 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 활동 현황 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 활동 현황 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 활동 현황 조회 해줘", "고객 활동 현황 조회 결과를 알려줘", "고객 활동 현황 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_consent_change
display_name: 고객 동의 정보 변경
version: 1.0.0
category_key: crm
description:
function: 고객 동의 정보 변경 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 동의 정보 변경 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 동의 정보 변경 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 동의 정보 변경 해줘", "고객 동의 정보 변경 결과를 알려줘", "고객 동의 정보 변경 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_consent_detail
display_name: 고객 동의 정보 조회
version: 1.0.0
category_key: crm
description:
function: 고객 동의 정보 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 동의 정보 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 동의 정보 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 동의 정보 조회 해줘", "고객 동의 정보 조회 결과를 알려줘", "고객 동의 정보 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_consultation_history
display_name: 고객 상담 이력 조회
version: 1.0.0
category_key: crm
description:
function: 고객 상담 이력 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 상담 이력 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 상담 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 상담 이력 조회 해줘", "고객 상담 이력 조회 결과를 알려줘", "고객 상담 이력 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_consultation_register
display_name: 고객 상담 이력 등록
version: 1.0.0
category_key: crm
description:
function: 고객 상담 이력 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 상담 이력 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 상담 이력 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 상담 이력 등록 해줘", "고객 상담 이력 등록 결과를 알려줘", "고객 상담 이력 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_contact_history
display_name: 고객 접촉 이력 조회
version: 1.0.0
category_key: crm
description:
function: 고객 접촉 이력 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 접촉 이력 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 접촉 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 접촉 이력 조회 해줘", "고객 접촉 이력 조회 결과를 알려줘", "고객 접촉 이력 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_contact_register
display_name: 고객 접촉 이력 등록
version: 1.0.0
category_key: crm
description:
function: 고객 접촉 이력 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 접촉 이력 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 접촉 이력 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 접촉 이력 등록 해줘", "고객 접촉 이력 등록 결과를 알려줘", "고객 접촉 이력 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_customer_create
display_name: 고객 정보 등록
version: 1.0.0
category_key: crm
description:
function: 고객 정보 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 정보 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 정보 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 정보 등록 해줘", "고객 정보 등록 결과를 알려줘", "고객 정보 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_customer_detail
display_name: 고객 상세 정보 조회
version: 1.0.0
category_key: crm
description:
function: 고객 상세 정보 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 상세 정보 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 상세 정보 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 상세 정보 조회 해줘", "고객 상세 정보 조회 결과를 알려줘", "고객 상세 정보 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_customer_duplicate_check
display_name: 고객 중복 여부 확인
version: 1.0.0
category_key: crm
description:
function: 고객 중복 여부 확인 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 중복 여부 확인 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 중복 여부 확인 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 중복 여부 확인 해줘", "고객 중복 여부 확인 결과를 알려줘", "고객 중복 여부 확인 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_customer_search
display_name: 고객 통합 조회
version: 1.0.0
category_key: crm
description:
function: 고객 통합 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 통합 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 통합 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 통합 조회 해줘", "고객 통합 조회 결과를 알려줘", "고객 통합 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_customer_update
display_name: 고객 정보 수정
version: 1.0.0
category_key: crm
description:
function: 고객 정보 수정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 정보 수정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 정보 수정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 정보 수정 해줘", "고객 정보 수정 결과를 알려줘", "고객 정보 수정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_grade_change
display_name: 고객 등급 변경
version: 1.0.0
category_key: crm
description:
function: 고객 등급 변경 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 등급 변경 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 등급 변경 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 등급 변경 해줘", "고객 등급 변경 결과를 알려줘", "고객 등급 변경 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_grade_detail
display_name: 고객 등급 조회
version: 1.0.0
category_key: crm
description:
function: 고객 등급 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 등급 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 등급 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 등급 조회 해줘", "고객 등급 조회 결과를 알려줘", "고객 등급 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_owner_assign
display_name: 고객 담당자 배정
version: 1.0.0
category_key: crm
description:
function: 고객 담당자 배정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 담당자 배정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 담당자 배정 해줘", "고객 담당자 배정 결과를 알려줘", "고객 담당자 배정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_segment_detail
display_name: 고객 세그먼트 조회
version: 1.0.0
category_key: crm
description:
function: 고객 세그먼트 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 세그먼트 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 세그먼트 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 세그먼트 조회 해줘", "고객 세그먼트 조회 결과를 알려줘", "고객 세그먼트 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: crm_tag_manage
display_name: 고객 태그 관리
version: 1.0.0
category_key: crm
description:
function: 고객 태그 관리 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객 태그 관리 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객 태그 관리 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객 태그 관리 해줘", "고객 태그 관리 결과를 알려줘", "고객 태그 관리 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [crm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_assign
display_name: VOC 담당자 배정
version: 1.0.0
category_key: voc
description:
function: VOC 담당자 배정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 담당자 배정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 담당자 배정 해줘", "VOC 담당자 배정 결과를 알려줘", "VOC 담당자 배정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_attachments
display_name: VOC 첨부파일 조회
version: 1.0.0
category_key: voc
description:
function: VOC 첨부파일 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 첨부파일 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 첨부파일 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 첨부파일 조회 해줘", "VOC 첨부파일 조회 결과를 알려줘", "VOC 첨부파일 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_change_status
display_name: VOC 처리 상태 변경
version: 1.0.0
category_key: voc
description:
function: VOC 처리 상태 변경 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 처리 상태 변경 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 처리 상태 변경 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 처리 상태 변경 해줘", "VOC 처리 상태 변경 결과를 알려줘", "VOC 처리 상태 변경 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_classify_type
display_name: VOC 유형 분류
version: 1.0.0
category_key: voc
description:
function: VOC 유형 분류 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 유형 분류 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 유형 분류 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 유형 분류 해줘", "VOC 유형 분류 결과를 알려줘", "VOC 유형 분류 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_customer_history
display_name: 고객별 VOC 이력 조회
version: 1.0.0
category_key: voc
description:
function: 고객별 VOC 이력 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 고객별 VOC 이력 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 고객별 VOC 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["고객별 VOC 이력 조회 해줘", "고객별 VOC 이력 조회 결과를 알려줘", "고객별 VOC 이력 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_detail
display_name: VOC 상세 조회
version: 1.0.0
category_key: voc
description:
function: VOC 상세 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 상세 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 상세 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 상세 조회 해줘", "VOC 상세 조회 결과를 알려줘", "VOC 상세 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_detect_duplicate
display_name: 중복 VOC 탐지
version: 1.0.0
category_key: voc
description:
function: 중복 VOC 탐지 기능을 수행합니다.
when_to_use: 고객채널 업무에서 중복 VOC 탐지 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 중복 VOC 탐지 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["중복 VOC 탐지 해줘", "중복 VOC 탐지 결과를 알려줘", "중복 VOC 탐지 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_extend_due_date
display_name: VOC 처리 기한 연장
version: 1.0.0
category_key: voc
description:
function: VOC 처리 기한 연장 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 처리 기한 연장 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 처리 기한 연장 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 처리 기한 연장 해줘", "VOC 처리 기한 연장 결과를 알려줘", "VOC 처리 기한 연장 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_register
display_name: VOC 접수 등록
version: 1.0.0
category_key: voc
description:
function: VOC 접수 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 접수 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 접수 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 접수 등록 해줘", "VOC 접수 등록 결과를 알려줘", "VOC 접수 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_register_result
display_name: VOC 처리 결과 등록
version: 1.0.0
category_key: voc
description:
function: VOC 처리 결과 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 처리 결과 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 처리 결과 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 처리 결과 등록 해줘", "VOC 처리 결과 등록 결과를 알려줘", "VOC 처리 결과 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_search
display_name: VOC 목록 검색
version: 1.0.0
category_key: voc
description:
function: VOC 목록 검색 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 목록 검색 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 목록 검색 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 목록 검색 해줘", "VOC 목록 검색 결과를 알려줘", "VOC 목록 검색 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_send_reply
display_name: VOC 답변 발송
version: 1.0.0
category_key: voc
description:
function: VOC 답변 발송 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 답변 발송 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 답변 발송 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 답변 발송 해줘", "VOC 답변 발송 결과를 알려줘", "VOC 답변 발송 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_set_priority
display_name: VOC 우선순위 설정
version: 1.0.0
category_key: voc
description:
function: VOC 우선순위 설정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 우선순위 설정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 우선순위 설정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 우선순위 설정 해줘", "VOC 우선순위 설정 결과를 알려줘", "VOC 우선순위 설정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_statistics
display_name: VOC 통계 조회
version: 1.0.0
category_key: voc
description:
function: VOC 통계 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 통계 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 통계 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 통계 조회 해줘", "VOC 통계 조회 결과를 알려줘", "VOC 통계 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_transfer
display_name: VOC 이관 처리
version: 1.0.0
category_key: voc
description:
function: VOC 이관 처리 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 이관 처리 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 이관 처리 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 이관 처리 해줘", "VOC 이관 처리 결과를 알려줘", "VOC 이관 처리 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_update
display_name: VOC 내용 수정
version: 1.0.0
category_key: voc
description:
function: VOC 내용 수정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 VOC 내용 수정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: VOC 내용 수정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["VOC 내용 수정 해줘", "VOC 내용 수정 결과를 알려줘", "VOC 내용 수정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: voc_urgent_list
display_name: 긴급 VOC 목록 조회
version: 1.0.0
category_key: voc
description:
function: 긴급 VOC 목록 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 긴급 VOC 목록 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 긴급 VOC 목록 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["긴급 VOC 목록 조회 해줘", "긴급 VOC 목록 조회 결과를 알려줘", "긴급 VOC 목록 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [voc, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_copy
display_name: 웹 콘텐츠 복사
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 복사 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 복사 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 복사 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 복사 해줘", "웹 콘텐츠 복사 결과를 알려줘", "웹 콘텐츠 복사 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_create
display_name: 웹 콘텐츠 등록
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 등록 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 등록 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 등록 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 등록 해줘", "웹 콘텐츠 등록 결과를 알려줘", "웹 콘텐츠 등록 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: false
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_delete
display_name: 웹 콘텐츠 삭제
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 삭제 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 삭제 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 삭제 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 삭제 해줘", "웹 콘텐츠 삭제 결과를 알려줘", "웹 콘텐츠 삭제 기능을 실행해줘"]
read_only: false
destructive: true
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_detail
display_name: 웹 콘텐츠 상세 조회
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 상세 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 상세 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 상세 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 상세 조회 해줘", "웹 콘텐츠 상세 조회 결과를 알려줘", "웹 콘텐츠 상세 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_list
display_name: 웹 콘텐츠 목록 조회
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 목록 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 목록 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 목록 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 목록 조회 해줘", "웹 콘텐츠 목록 조회 결과를 알려줘", "웹 콘텐츠 목록 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_preview
display_name: 웹 콘텐츠 미리보기
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 미리보기 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 미리보기 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 미리보기 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 미리보기 해줘", "웹 콘텐츠 미리보기 결과를 알려줘", "웹 콘텐츠 미리보기 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_publish
display_name: 웹 콘텐츠 게시
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 게시 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 게시 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 게시 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 게시 해줘", "웹 콘텐츠 게시 결과를 알려줘", "웹 콘텐츠 게시 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_request_approval
display_name: 웹 콘텐츠 승인 요청
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 승인 요청 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 승인 요청 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 승인 요청 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 승인 요청 해줘", "웹 콘텐츠 승인 요청 결과를 알려줘", "웹 콘텐츠 승인 요청 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_restore_version
display_name: 웹 콘텐츠 이전 버전 복원
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 이전 버전 복원 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 이전 버전 복원 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 이전 버전 복원 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 이전 버전 복원 해줘", "웹 콘텐츠 이전 버전 복원 결과를 알려줘", "웹 콘텐츠 이전 버전 복원 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_review_approval
display_name: 웹 콘텐츠 승인·반려
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 승인·반려 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 승인·반려 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 승인·반려 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 승인·반려 해줘", "웹 콘텐츠 승인·반려 결과를 알려줘", "웹 콘텐츠 승인·반려 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_schedule_publish
display_name: 웹 콘텐츠 예약 게시
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 예약 게시 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 예약 게시 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 예약 게시 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 예약 게시 해줘", "웹 콘텐츠 예약 게시 결과를 알려줘", "웹 콘텐츠 예약 게시 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_unpublish
display_name: 웹 콘텐츠 게시 중지
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 게시 중지 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 게시 중지 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 게시 중지 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 게시 중지 해줘", "웹 콘텐츠 게시 중지 결과를 알려줘", "웹 콘텐츠 게시 중지 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_update
display_name: 웹 콘텐츠 수정
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 수정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 수정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 수정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 수정 해줘", "웹 콘텐츠 수정 결과를 알려줘", "웹 콘텐츠 수정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_content_version_history
display_name: 웹 콘텐츠 버전 이력 조회
version: 1.0.0
category_key: wcm
description:
function: 웹 콘텐츠 버전 이력 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 웹 콘텐츠 버전 이력 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 웹 콘텐츠 버전 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["웹 콘텐츠 버전 이력 조회 해줘", "웹 콘텐츠 버전 이력 조회 결과를 알려줘", "웹 콘텐츠 버전 이력 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_metadata_detail
display_name: 콘텐츠 메타데이터 조회
version: 1.0.0
category_key: wcm
description:
function: 콘텐츠 메타데이터 조회 기능을 수행합니다.
when_to_use: 고객채널 업무에서 콘텐츠 메타데이터 조회 기능이 필요할 때 사용합니다.
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 콘텐츠 메타데이터 조회 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["콘텐츠 메타데이터 조회 해줘", "콘텐츠 메타데이터 조회 결과를 알려줘", "콘텐츠 메타데이터 조회 기능을 실행해줘"]
read_only: true
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 조회, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_metadata_upsert
display_name: 콘텐츠 메타데이터 등록·수정
version: 1.0.0
category_key: wcm
description:
function: 콘텐츠 메타데이터 등록·수정 기능을 수행합니다.
when_to_use: 고객채널 업무에서 콘텐츠 메타데이터 등록·수정 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 콘텐츠 메타데이터 등록·수정 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["콘텐츠 메타데이터 등록·수정 해줘", "콘텐츠 메타데이터 등록·수정 결과를 알려줘", "콘텐츠 메타데이터 등록·수정 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,30 +0,0 @@
name: wcm_taxonomy_manage
display_name: 콘텐츠 카테고리·태그 관리
version: 1.0.0
category_key: wcm
description:
function: 콘텐츠 카테고리·태그 관리 기능을 수행합니다.
when_to_use: 고객채널 업무에서 콘텐츠 카테고리·태그 관리 기능이 필요할 때 사용합니다.
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
display_description: 콘텐츠 카테고리·태그 관리 기능을 안전한 모의 데이터로 제공합니다.
example_queries: ["콘텐츠 카테고리·태그 관리 해줘", "콘텐츠 카테고리·태그 관리 결과를 알려줘", "콘텐츠 카테고리·태그 관리 기능을 실행해줘"]
read_only: false
destructive: false
idempotent: true
parameters_schema:
type: object
properties:
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
page: {type: integer, description: 페이지 번호, minimum: 0}
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
additionalProperties: false
tags: [wcm, 고객채널, 처리, mock]
required_env_keys: []
owner_org: MCP_TOOL

View File

@@ -1,60 +0,0 @@
plugins {
// Gateway와 모든 Tool Pod가 의존하는 공통 라이브러리 모듈입니다.
id 'java-library'
}
dependencies {
// 공통 REST Controller, HTTP Client, 예외 처리 기반입니다.
api 'org.springframework.boot:spring-boot-starter-web'
// Tool Request DTO의 Bean Validation을 지원합니다.
api 'org.springframework.boot:spring-boot-starter-validation'
// Tool Manifest/Registry 캐시 및 Redis 기반 공통 기능을 제공합니다.
api 'org.springframework.boot:spring-boot-starter-data-redis'
// Tool SLA, 로깅, 공통 Aspect를 적용합니다.
api 'org.springframework.boot:spring-boot-starter-aop'
// MCI/DB 연동에 필요한 JDBC 공통 기능입니다.
api 'org.springframework.boot:spring-boot-starter-jdbc'
// Tool 호출의 Circuit Breaker, Rate Limit, Retry 등 복원력 기능입니다.
api 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
api 'io.github.resilience4j:resilience4j-core:2.2.0'
api 'io.github.resilience4j:resilience4j-circuitbreaker:2.2.0'
api 'io.github.resilience4j:resilience4j-ratelimiter'
api 'io.github.resilience4j:resilience4j-retry:2.2.0'
// MCI/업무 데이터 접근을 위한 MyBatis 지원입니다.
api 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
// 현재 로컬 테스트 DB 및 SQL 로그 처리에 사용합니다.
api 'com.h2database:h2'
api 'p6spy:p6spy:3.9.1'
// Spring Data Redis가 사용하는 Redis Client를 공통 모듈에서 직접 참조합니다.
api 'io.lettuce:lettuce-core:6.6.0.RELEASE'
// MCI XML 전문, JSON Tool Schema/Manifest 처리에 사용합니다.
api 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'
api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
api 'com.fasterxml.jackson.core:jackson-databind'
// MCP Java SDK 2.0.0의 mcp-json-jackson2가 호출하는 Schema API와 반드시 맞춘다.
// 3.x는 Schema.validate(JsonNode) 반환 규격이 달라 런타임 NoSuchMethodError가 발생한다.
api 'com.networknt:json-schema-validator:2.0.0'
// Boot 3.5.11 위에서 MCP Java SDK 2.0.0의 Server/Client와 Servlet 전송 계층을 사용합니다.
// Jackson 2 공급자를 명시해 Boot 3의 Jackson 계열과 맞춥니다.
api 'io.modelcontextprotocol.sdk:mcp-core'
api 'io.modelcontextprotocol.sdk:mcp-json-jackson2'
// Boot 3.5 호환 Spring AI 어노테이션 API를 유지합니다.
api 'org.springaicommunity:mcp-annotations:0.9.0'
// 이벤트 기반 확장이 필요한 Tool의 공통 Kafka 연동 기능입니다.
api 'org.springframework.kafka:spring-kafka:3.2.0'
// Tool Pod REST API 문서 및 Swagger UI를 제공합니다.
api 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
}

View File

@@ -1,32 +0,0 @@
package io.shinhanlife.dap.lib.adapter.dto;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* @package io.shinhanlife.dap.lib.adapter.dto
* @className ErrorDetail
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Setter
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class ErrorDetail {
private int code;
private String message;
}

View File

@@ -1,27 +0,0 @@
package io.shinhanlife.dap.lib.adapter.dto;
import lombok.Getter;
import lombok.Setter;
/**
* @package io.shinhanlife.dap.lib.adapter.dto
* @className JsonRpcRequest
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Setter
public class JsonRpcRequest {
private String jsonrpc;
private String method;
private Params params;
private String id;
}

View File

@@ -1,30 +0,0 @@
package io.shinhanlife.dap.lib.adapter.dto;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Getter;
import lombok.Setter;
// 2. 응답 DTO
/**
* @package io.shinhanlife.dap.lib.adapter.dto
* @className JsonRpcResponse
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Setter
@JsonPropertyOrder({"jsonrpc", "result", "error", "id"})
public class JsonRpcResponse {
public String jsonrpc = "2.0";
public Object result;
public Object error;
public String id;
}

View File

@@ -1,38 +0,0 @@
package io.shinhanlife.dap.lib.adapter.dto;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
/**
* @package io.shinhanlife.dap.lib.adapter.dto
* @className Params
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Params {
private String routingType;
private String name;
private String interfaceId;
private Map<String, Object> data;
private List<Map<String, Object>> spec;
}

View File

@@ -1,61 +0,0 @@
package io.shinhanlife.dap.lib.adapter.test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Local HTTP mock server for scaffolded HTTP Tools.
*
* <p>Each Tool Pod returns the JSON generated under
* {@code src/main/resources/mock-responses/{toolName}.json}. It is enabled only
* when {@code axhub.mock.http.enabled=true}, which the HTTP Scaffold adds to local configuration.</p>
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "axhub.mock.http", name = "enabled", havingValue = "true")
@RequestMapping("/api")
public class MockEimsHttpServer {
private final ObjectMapper objectMapper;
@PostMapping("/mock/http/{toolName:[a-z0-9_-]+}")
public ResponseEntity<JsonNode> mockToolHttpResponse(
@PathVariable String toolName,
@RequestBody(required = false) JsonNode request) {
ClassPathResource resource = new ClassPathResource("mock-responses/" + toolName + ".json");
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
try {
log.info("[MockEimsHttpServer] HTTP mock request. toolName={}, body={}", toolName, request);
return ResponseEntity.ok(objectMapper.readTree(resource.getInputStream()));
} catch (Exception e) {
log.warn("[MockEimsHttpServer] Unable to read mock response. toolName={}", toolName, e);
return ResponseEntity.internalServerError().build();
}
}
@PostMapping("/gateway")
public ResponseEntity<?> mockEimsReceiver(
@RequestHeader(value = "X-Trace-Id", required = false) String traceId,
@RequestBody Map<String, Object> request) {
String interfaceId = String.valueOf(request.getOrDefault("interfaceId", ""));
log.info("[MockEimsHttpServer] Legacy gateway mock request. traceId={}, interfaceId={}", traceId, interfaceId);
return ResponseEntity.ok(Map.of(
"status", "404",
"message", "MOCK data is not defined for interfaceId: " + interfaceId));
}
}

View File

@@ -1,35 +0,0 @@
package io.shinhanlife.dap.lib.adapter.util;
import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
/**
* Logback 커스텀 컨버터
* 모든 로그 메시지(%msg)가 파일이나 콘솔에 찍히기 직전에 이 클래스를 거쳐가게 됩니다.
* 여기서 PiiMaskingUtils.mask()를 호출하여 PII(주민번호, 계좌번호 등)를 안전하게 별표(*) 처리합니다.
*/
/**
* @package io.shinhanlife.dap.lib.adapter.util
* @className PiiMaskingLogbackConverter
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
public class PiiMaskingLogbackConverter extends MessageConverter {
@Override
public String convert(ILoggingEvent event) {
// 원본 로그 메시지를 가져옵니다.
String originalMessage = super.convert(event);
// 정규식을 이용하여 개인정보가 포함되어 있으면 마스킹 처리하여 반환합니다.
return PiiMaskingUtils.mask(originalMessage);
}
}

View File

@@ -1,77 +0,0 @@
package io.shinhanlife.dap.lib.adapter.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @package io.shinhanlife.dap.lib.adapter.util
* @className PiiMaskingUtils
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
public class PiiMaskingUtils {
// 1. 주민등록번호 패턴 (ex: 900101-1234567 또는 9001011234567)
private static final Pattern RRN_PATTERN = Pattern.compile("(\\d{6})[-]?([1-4]\\d{6})");
// 2. 휴대전화번호 패턴 (ex: 010-1234-5678)
private static final Pattern PHONE_PATTERN = Pattern.compile("(01[016789])[-]?(\\d{3,4})[-]?(\\d{4})");
// 3. 신한라이프 계좌/증권번호 패턴 (단순 예시용 계좌번호 11~14자리)
private static final Pattern ACCOUNT_PATTERN = Pattern.compile("(\\d{3})-?(\\d{3})-?(\\d{5,8})");
public static String mask(String input) {
if (input == null || input.isEmpty()) {
return input;
}
String masked = input;
// [1] 주민번호 뒷자리 마스킹 (첫자리 성별 식별자는 남기고 마스킹: 900101-1******)
Matcher rrnMatcher = RRN_PATTERN.matcher(masked);
StringBuffer rrnBuffer = new StringBuffer();
while (rrnMatcher.find()) {
String firstPart = rrnMatcher.group(1);
String secondPart = rrnMatcher.group(2);
rrnMatcher.appendReplacement(rrnBuffer, firstPart + "-" + secondPart.charAt(0) + "******");
}
rrnMatcher.appendTail(rrnBuffer);
masked = rrnBuffer.toString();
// [2] 전화번호 중간자리 마스킹 (010-****-5678)
Matcher phoneMatcher = PHONE_PATTERN.matcher(masked);
StringBuffer phoneBuffer = new StringBuffer();
while (phoneMatcher.find()) {
String p1 = phoneMatcher.group(1);
String p2 = phoneMatcher.group(2);
String p3 = phoneMatcher.group(3);
String maskedP2 = p2.replaceAll(".", "*");
phoneMatcher.appendReplacement(phoneBuffer, p1 + "-" + maskedP2 + "-" + p3);
}
phoneMatcher.appendTail(phoneBuffer);
masked = phoneBuffer.toString();
// [3] 계좌번호 뒷자리 마스킹 (110-123-********)
Matcher accMatcher = ACCOUNT_PATTERN.matcher(masked);
StringBuffer accBuffer = new StringBuffer();
while (accMatcher.find()) {
String a1 = accMatcher.group(1);
String a2 = accMatcher.group(2);
String a3 = accMatcher.group(3);
String maskedA3 = a3.replaceAll(".", "*");
accMatcher.appendReplacement(accBuffer, a1 + "-" + a2 + "-" + maskedA3);
}
accMatcher.appendTail(accBuffer);
masked = accBuffer.toString();
return masked;
}
}

View File

@@ -1,45 +0,0 @@
package io.shinhanlife.dap.lib.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Spring AI @Tool 어노테이션을 보완하여 MCP 시스템 메타데이터를 추가 제공하는 힌트 어노테이션
* @package io.shinhanlife.dap.lib.annotation
* @className GrowToolHint
* @description 비즈니스 로직(Tool)과 시스템 제어 메타데이터 분리
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GrowToolHint {
boolean register() default true;
boolean requiresApproval() default false;
String categoryKey() default "com";
String mappingId() default "";
String inputSchemaResource() default "";
String outputSchemaResource() default "";
// Meta 정보 추가 (보고용 샘플)
String displayDescription() default "";
String functionDescription() default "";
String whenToUse() default "";
String whenNotToUse() default "";
String ioLimits() default "";
String[] exampleQueries() default {};
boolean destructive() default false;
boolean idempotent() default false;
String[] tags() default {};
String[] requiredEnvKeys() default {};
String ownerOrg() default "";
}

View File

@@ -1,14 +0,0 @@
package io.shinhanlife.dap.lib.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a response DTO whose generated JSON Schema must be exposed and validated for a Tool response.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface McpOutputSchema {
}

View File

@@ -1,83 +0,0 @@
package io.shinhanlife.dap.lib.aop;
/**
* @package io.shinhanlife.dap.lib.aop
* @className ToolSlaMonitoringAspect
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
import io.shinhanlife.dap.lib.config.McpProperties;
import java.lang.reflect.Method;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springaicommunity.mcp.annotation.McpTool;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class ToolSlaMonitoringAspect {
private final McpProperties mcpProperties;
// @McpTool 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
@Around("@annotation(org.springaicommunity.mcp.annotation.McpTool)")
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
McpTool functionAnnotation = method.getAnnotation(McpTool.class);
// 네임스페이스 자동 주입 로직을 반영하여 최종 툴 이름을 산출합니다.
String baseName = functionAnnotation.name();
String finalName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
? mcpProperties.getNamespace() + "_" + baseName
: baseName;
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try {
// 실제 비즈니스 로직(툴) 실행
Object result = joinPoint.proceed();
stopWatch.stop();
long timeMillis = stopWatch.getTotalTimeMillis();
// SLA 기준을 초과하면 (예: 2초 이상) 경고 로깅 처리 가능
if (timeMillis > 2000) {
log.warn(" [SLA 경고] Tool: {} | 소요시간: {}ms | 상태: SLOW_RESPONSE", finalName, timeMillis);
} else {
log.info(" [SLA 추적] Tool: {} | 소요시간: {}ms | 상태: SUCCESS", finalName, timeMillis);
}
return result;
} catch (Throwable e) {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
long timeMillis = stopWatch.getTotalTimeMillis();
// 에러 발생 시 명확하게 실패 로그 기록
log.error(" [SLA 장애] Tool: {} | 소요시간: {}ms | 상태: FAILED | 사유: {}", finalName, timeMillis, e.getMessage());
// 원래 흐름대로 예외를 던져서 게이트웨이나 상위 로직이 에러를 처리하게 함
throw e;
}
}
}

View File

@@ -1,29 +0,0 @@
package io.shinhanlife.dap.lib.config;
import io.shinhanlife.glow.communication.module.http.component.GlowHttpComponent;
import java.net.http.HttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
/**
* Registers the temporary Glow HTTP compatibility component from the DAP library scan scope.
* The bean is only created when an official GlowHttpComponent has not already been supplied.
*/
@Configuration(proxyBeanMethods = false)
public class AxhubHttpConfiguration {
@Bean
@ConditionalOnMissingBean(GlowHttpComponent.class)
public GlowHttpComponent glowHttpComponent(RestClient.Builder restClientBuilder) {
// WireMock and legacy internal endpoints can only support HTTP/1.1.
// Avoid JDK HTTP/2 negotiation that may cause RST_STREAM responses.
HttpClient http11Client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
JdkClientHttpRequestFactory requestFactory = new JdkClientHttpRequestFactory(http11Client);
return new GlowHttpComponent(restClientBuilder.requestFactory(requestFactory));
}
}

View File

@@ -1,34 +0,0 @@
package io.shinhanlife.dap.lib.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @package io.shinhanlife.dap.lib.config
* @className CorsConfig
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 모든 엔드포인트에 대해 CORS 허용
.allowedOriginPatterns("*") // 외부 Agent Builder 등 모든 오리진 허용
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH") // 허용할 HTTP 메서드
.allowedHeaders("*") // 모든 헤더 허용
.exposedHeaders("Mcp-Session-Id") // MCP-HTTP 세션 아이디 노출 허용
.allowCredentials(true) // 쿠키/인증 정보 허용
.maxAge(3600); // preflight 요청 캐시 시간 (초 단위)
}
}

View File

@@ -1,85 +0,0 @@
package io.shinhanlife.dap.lib.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* [Glow Framework 통신 환경 설정 클래스]
* application-glow-local.yml 의 'glow.communication' 하위 설정값들을
* 자바 객체(Bean)로 매핑하여 제공합니다.
*/
/**
* @package io.shinhanlife.dap.lib.config
* @className GlowCommunicationProperties
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Component
@Getter
@Setter
@ConfigurationProperties(prefix = "glow.communication")
public class GlowCommunicationProperties {
private Common common = new Common();
private Http http = new Http();
private Mci mci = new Mci();
private ExtMci extmci = new ExtMci();
private Eai eai = new Eai();
private Websocket websocket = new Websocket();
@Getter @Setter
public static class Common {
private String envType; // 대내표준 헤더의 환경 타입정보 (D, T, P)
}
@Getter @Setter
public static class Http {
private int connectionTimeout; // 연결 타임아웃 시간 (초 단위)
private int readTimeout; // 읽기 타임아웃 시간 (초 단위)
}
@Getter @Setter
public static class Mci {
private String host;
private int port;
private String uri;
private String receiveUri;
private int connectionTimeout;
private int readTimeout;
private String encoding;
}
@Getter @Setter
public static class ExtMci {
private String host;
private int port;
private String uri;
private String jsonUri;
private String receiveUri;
private int connectionTimeout;
private int readTimeout;
private String encoding;
}
@Getter @Setter
public static class Eai {
private String host;
private int port;
}
@Getter @Setter
public static class Websocket {
private String endpoint;
private String allowedOrigins;
}
}

View File

@@ -1,37 +0,0 @@
package io.shinhanlife.dap.lib.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @package io.shinhanlife.dap.lib.config
* @className McpProperties
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "mcp")
public class McpProperties {
private String namespace;
private Manifest manifest = new Manifest();
@Data
public static class Manifest {
private String bundleId;
private String namePrefix;
}
}

View File

@@ -1,37 +0,0 @@
package io.shinhanlife.dap.lib.config;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @package io.shinhanlife.dap.lib.config
* @className MybatisConfig
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
import org.mybatis.spring.annotation.MapperScan;
import io.shinhanlife.glow.GlowMybatisMapper;
@Configuration
@MapperScan(basePackages = "io.shinhanlife.dap", annotationClass = GlowMybatisMapper.class)
public class MybatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
return sessionFactory.getObject();
}
}

View File

@@ -1,54 +0,0 @@
package io.shinhanlife.dap.lib.config;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
/**
* @package io.shinhanlife.dap.lib.config
* @className P6SpySqlFormatter
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
public class P6SpySqlFormatter implements MessageFormattingStrategy {
@Override
public String formatMessage(int connectionId, String now, long elapsed,
String category, String prepared, String sql, String url) {
if (sql == null || sql.isBlank()) return "";
if (Category.STATEMENT.getName().equals(category)) {
String prettySQL = sql
.replaceAll("(?i)\\bSELECT\\b", "\nSELECT")
.replaceAll("(?i)\\bFROM\\b", "\n FROM")
.replaceAll("(?i)\\bWHERE\\b", "\n WHERE")
.replaceAll("(?i)\\bAND\\b", "\n AND")
.replaceAll("(?i)\\bOR\\b", "\n OR")
.replaceAll("(?i)\\bINNER JOIN\\b", "\n INNER JOIN")
.replaceAll("(?i)\\bLEFT JOIN\\b", "\n LEFT JOIN")
.replaceAll("(?i)\\bORDER BY\\b", "\n ORDER BY")
.replaceAll("(?i)\\bGROUP BY\\b", "\n GROUP BY")
.replaceAll("(?i)\\bINSERT INTO\\b", "\nINSERT INTO")
.replaceAll("(?i)\\bVALUES\\b", "\n VALUES")
.replaceAll("(?i)\\bUPDATE\\b", "\nUPDATE")
.replaceAll("(?i)\\bSET\\b", "\n SET")
.replaceAll("(?i)\\bDELETE FROM\\b", "\nDELETE FROM");
return String.format("""
\n┌─────────────────────────────────────────
│ SQL [%dms]
│%s
└─────────────────────────────────────────
""", elapsed, prettySQL.indent(2).stripTrailing());
}
return "";
}
}

View File

@@ -1,32 +0,0 @@
package io.shinhanlife.dap.lib.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
import io.modelcontextprotocol.json.schema.jackson2.DefaultJsonSchemaValidator;
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Common MCP Tool Schema Bean configuration.
*/
@Configuration
public class ToolSchemaConfiguration {
@Bean
public ToolSchemaResolver toolSchemaResolver(ObjectMapper objectMapper) {
return new ToolSchemaResolver(objectMapper);
}
@Bean
public JsonSchemaValidator mcpJsonSchemaValidator() {
return new DefaultJsonSchemaValidator();
}
@Bean
public ToolArgumentSchemaValidator toolArgumentSchemaValidator(ObjectMapper objectMapper,
JsonSchemaValidator jsonSchemaValidator) {
return new ToolArgumentSchemaValidator(objectMapper, jsonSchemaValidator);
}
}

View File

@@ -1,20 +0,0 @@
package io.shinhanlife.dap.lib.dto;
/**
* @package io.shinhanlife.dap.mcg.dto
* @className OperationType
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
public enum OperationType {
READ,
WRITE
}

View File

@@ -1,105 +0,0 @@
package io.shinhanlife.dap.lib.integration;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
// TODO: 실제 Glow Framework 의존성이 추가되면 아래 주석들을 풀고 사용하세요!
// import io.shinhanlife.glow.communication.dto.CommonHeader;
// import io.shinhanlife.glow.communication.dto.Transfer;
// import io.shinhanlife.glow.communication.module.eai.component.GlowEaiComponent;
// import io.shinhanlife.glow.communication.module.mci.component.GlowExtMciComponent;
// import io.shinhanlife.glow.communication.module.mci.component.GlowMciComponent;
// import io.shinhanlife.glow.communication.util.CommonHeaderFactory;
/**
* [MCI / EAI 공통 연동 래퍼(Wrapper) 템플릿]
* 신한라이프 Glow Framework 개발표준정의서를 바탕으로 대내/대외망/EAI 통신을
* MCP 툴에서 손쉽게 호출할 수 있도록 일원화한 컴포넌트입니다.
*/
/**
* @package io.shinhanlife.dap.lib.integration
* @className GlowIntegrationCall
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Component
@RequiredArgsConstructor
public class GlowIntegrationCall {
// 1. 실제 의존성이 주입될 프레임워크 컴포넌트들 (임시 주석 처리)
/*
private final GlowMciComponent mci;
private final GlowEaiComponent eai;
private final GlowExtMciComponent extMci;
*/
/**
* 1. 대외 MCI 호출 (타행, 금융결제원 등 외부 기관)
* 가이드 2.2.2에 명시된 필수 파라미터(기관코드, 종별코드, 업무코드, 거래코드)를 모두 포함합니다.
*/
/*
public <S, R> Transfer<R> callExtMci(String itrfId, String frbuCd, String cmouDutjCd, String cmouCssfCd, String cmouTraCd, S body, Class<R> resBody) {
// 1. 공통 헤더 생성
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
// 2. 대외 전용 필수 코드 세팅 로직 (프레임워크 내부 스펙에 맞게 가공)
// (예: 헤더에 해당 속성들을 주입하거나 Transfer 객체에 싣는 과정 추가)
// 3. Transfer 객체 빌드
Transfer<S> req = Transfer.<S>builder()
.header(header)
.body(body)
.build();
// 4. 대외 MCI 컴포넌트를 통해 최종 전송
return extMci.call(req, resBody);
}
*/
/**
* 2. EAI 호출 (대내망 중계기)
* 가이드 2.3에 명시된 대로 수신서비스 ID 없이 인터페이스 ID(itrfId)만 필수로 받습니다.
*/
/*
public <S, R> Transfer<R> callEai(String itrfId, S body, Class<R> resBody) {
// 1. EAI는 인터페이스 ID만으로 심플하게 헤더 생성
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
// 2. Transfer 객체 빌드
Transfer<S> req = Transfer.<S>builder()
.header(header)
.body(body)
.build();
// 3. EAI 컴포넌트를 통해 최종 전송
return eai.call(req, resBody);
}
*/
/**
* 3. 대내 MCI 호출 (사내 시스템 간 통신)
*/
/*
public <S, R> Transfer<R> callMci(String itrfId, S body, Class<R> resBody) {
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
Transfer<S> req = Transfer.<S>builder()
.header(header)
.body(body)
.build();
return mci.call(req, resBody);
}
*/
}

View File

@@ -1,84 +0,0 @@
package io.shinhanlife.dap.lib.integration.dto;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;
// TODO: 실제 Glow Framework 의존성이 추가되면 아래 주석을 풀고 사용하세요!
// import io.shinhanlife.glow.communication.annotation.GlowMciFieldInfo;
/**
* [대외 MCI 연동용 DTO 표준 템플릿]
* Glow Framework 개발표준정의서(2.2.1 IO 작성) 규칙을 100% 준수한 샘플입니다.
* 새로운 대외 통신 전문을 만들 때 이 파일을 복사해서 필드명과 길이만 수정하여 사용하세요.
*/
/**
* @package io.shinhanlife.dap.lib.integration.dto
* @className SampleGlowMessage
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC) // [규칙 1] Reflection을 위한 기본 생성자 필수 (public 유지)
public class SampleGlowMessage {
// [규칙 2] @GlowMciFieldInfo 선언 필수 (order: 순서)
// @GlowMciFieldInfo(order = 1)
private MessageHeader header;
// [규칙 2] @GlowMciFieldInfo 선언 필수 (order: 순서)
// @GlowMciFieldInfo(order = 2)
private List<MessageBody> msgDtdvValu; // 다건(List) 본문 데이터
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public static class MessageHeader {
// [규칙 2] 단건 필드의 경우 length 필수 입력 (EIMS 길이와 일치해야 함)
// @GlowMciFieldInfo(order = 1, length = 1)
private String msgTnsmTypeCd;
// @GlowMciFieldInfo(order = 2, length = 8)
private int msdvLen;
// [규칙 3] 다건(List) 건수 필드의 경우, target 속성에 대상 변수명("msgDtdvValu") 필수 기입!
// @GlowMciFieldInfo(order = 3, length = 2, target = "msgDtdvValu")
private int msgRpttCc;
}
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public static class MessageBody {
// @GlowMciFieldInfo(order = 1, length = 8)
private String msgCd;
// @GlowMciFieldInfo(order = 2, length = 1)
private String msgPrnAttrCd;
// @GlowMciFieldInfo(order = 3, length = 200)
private String msgCt;
// @GlowMciFieldInfo(order = 4, length = 200)
private String anxMsgCt;
}
}

View File

@@ -1,99 +0,0 @@
package io.shinhanlife.dap.lib.integration.eai.component;
import io.shinhanlife.dap.lib.config.GlowCommunicationProperties;
import io.shinhanlife.glow.communication.dto.CommonHeader;
import io.shinhanlife.glow.communication.dto.Transfer;
import io.shinhanlife.glow.communication.module.eai.component.GlowEaiComponent;
import io.shinhanlife.glow.communication.util.CommonHeaderFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 신한라이프 내부 Glow 표준 EAI 컴포넌트 어댑터 (AXHUB)
*/
@Slf4j
@Component
@RequiredArgsConstructor
/**
* @package io.shinhanlife.dap.lib.integration.eai.component
* @className AxhubEaiComponent
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
public class AxhubEaiComponent {
@SuppressWarnings("rawtypes")
private final GlowEaiComponent eai;
private final GlowCommunicationProperties communicationProperties;
@SuppressWarnings("unchecked")
private <O> Transfer<O> syncEai(Transfer<Object> request) {
// LOG 저장 (AXHUB 방식 로깅)
CommonHeader reqHeader = (CommonHeader) request.getHeader();
log.info("[AxhubEaiComponent] {} EAI 호출시작 (수신서비스: {})", reqHeader.getItrfId(), reqHeader.getRcvSvcId());
Transfer<O> response = (Transfer<O>) eai.sync(request);
log.info("[AxhubEaiComponent] {} EAI 호출종료 (수신서비스: {})", reqHeader.getItrfId(), reqHeader.getRcvSvcId());
return response;
}
/**
* EAI 호출
*/
public <O, I> Transfer<O> call(String itrfId, String rcvSvcId, I inputDto) throws Exception {
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId, rcvSvcId);
Transfer<Object> request = Transfer.builder()
.header(header)
.body(inputDto)
.build();
return syncEai(request);
}
/**
* EAI 호출 (응답 타입 명시)
*/
@SuppressWarnings("unchecked")
public <O, I> Transfer<O> call(String itrfId, String rcvSvcId, I inputDto, Class<O> resBodyClass) throws Exception {
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId, rcvSvcId);
Transfer<Object> request = Transfer.builder()
.header(header)
.body(inputDto)
.resBodyClass((Class<Object>) (Class<?>) resBodyClass)
.build();
return syncEai(request);
}
/**
* EAI 호출 (rcvSvcId 없는 경우)
*/
public <O, I> Transfer<O> call(String itrfId, I inputDTO, Class<O> resBodyClass) throws Exception {
String className = inputDTO.getClass().getSimpleName();
String rcvSvcId = className.replace("_I", "");
return call(itrfId, rcvSvcId, inputDTO, resBodyClass);
}
/**
* EAI 호출 (Response body class와 rcvSvcId 없는 경우)
*/
public <O, I> Transfer<O> call(String itrfId, I inputDTO) throws Exception {
String className = inputDTO.getClass().getSimpleName();
String rcvSvcId = className.replace("_I", "");
return call(itrfId, rcvSvcId, inputDTO);
}
}

View File

@@ -1,142 +0,0 @@
package io.shinhanlife.dap.lib.integration.http.component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.shinhanlife.dap.lib.config.GlowCommunicationProperties;
import io.shinhanlife.dap.lib.mcp.McpRequestHeaderContext;
import io.shinhanlife.dap.lib.mcp.McpRequestHeaders;
import io.shinhanlife.glow.communication.module.http.component.GlowHttpComponent;
import io.shinhanlife.glow.communication.module.http.dto.HttpBody;
import io.shinhanlife.glow.communication.module.http.dto.HttpHeader;
import io.shinhanlife.glow.communication.module.http.dto.HttpTransfer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
/**
* Tool Pod outbound HTTP component using the Glow HTTP client.
* Target URL, HTTP method, content type and Pod-to-Pod behaviour are resolved from
* {@code glow.communication.http.api-list}; business source code does not own endpoint values.
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AxhubHttpComponent {
private static final String ANONYMOUS_REQUEST = "AXHUB-TOOL";
private final GlowHttpComponent http;
private final ObjectMapper json;
private final GlowCommunicationProperties communicationProperties;
private final AxhubHttpProperties properties;
/** Calls the exact URL configured for the API name. */
public <T, R> R call(String apiName, T inputDto, Class<R> responseBodyClass) {
return call(apiName, "", inputDto, responseBodyClass, 0);
}
/** Calls the configured URL with an optional resource suffix. */
public <T, R> R call(String apiName, String uri, T inputDto, Class<R> responseBodyClass) {
return call(apiName, uri, inputDto, responseBodyClass, 0);
}
public <T, R> R call(String apiName, String uri, T inputDto, Class<R> responseBodyClass, int timeout) {
AxhubHttpProperties.ApiDefinition api = resolveApi(apiName);
return execute(api, uri, inputDto, responseBodyClass, timeout);
}
/** Calls the configured URL only when the target is marked as a business Pod. */
public <T, R> R callBizPod(String apiName, T inputDto, Class<R> responseBodyClass) {
AxhubHttpProperties.ApiDefinition api = resolveApi(apiName);
if (!api.bizPod()) {
throw new IllegalArgumentException("Configured API is not a business Pod: " + apiName);
}
return execute(api, "", inputDto, responseBodyClass, 0);
}
private <T, R> R execute(AxhubHttpProperties.ApiDefinition api, String uri, T inputDto,
Class<R> responseBodyClass, int timeout) {
HttpHeader header = createHeader(api, timeout);
String requestUri = joinPath(api.url(), uri);
HttpTransfer<T> request = HttpTransfer.<T>http()
.header(header)
.domain(api.domain())
.uri(requestUri)
.method(api.method())
.contentType(contentType(api))
.responseEntity(responseBodyClass)
.body(inputDto)
.build();
log.info("[AxhubHttpComponent] Glow HTTP call. apiName={}, method={}, uri={}",
api.name(), api.method(), requestUri);
ResponseEntity<HttpBody> response = http.sync(request);
return convertResponse(response.getBody(), responseBodyClass);
}
private AxhubHttpProperties.ApiDefinition resolveApi(String apiName) {
return properties.getApiList().stream()
.filter(api -> apiName != null && apiName.equals(api.name()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No HTTP API configuration for name: " + apiName));
}
private HttpHeader createHeader(AxhubHttpProperties.ApiDefinition api, int timeout) {
HttpHeader header = new HttpHeader();
if (api.bizPod()) {
header.set("X-POD-TO-POD", "true");
}
McpRequestHeaders inbound = McpRequestHeaderContext.current();
if (inbound == null) {
header.set("X-ANONYMOUS-REQ", ANONYMOUS_REQUEST);
} else {
putIfPresent(header, "x-request-id", inbound.requestId());
putIfPresent(header, "guid", inbound.guid());
putIfPresent(header, "mcp-session-id", inbound.mcpSessionId());
putIfPresent(header, "employee-no", inbound.employeeNo());
putIfPresent(header, "virtual-employee-no", inbound.virtualEmployeeNo());
}
header.setReadTimeout(timeout == 0 ? defaultReadTimeout() : timeout);
return header;
}
private int defaultReadTimeout() {
return communicationProperties == null || communicationProperties.getHttp() == null
? 0 : communicationProperties.getHttp().getReadTimeout();
}
private MediaType contentType(AxhubHttpProperties.ApiDefinition api) {
return api.contentType() == null || api.contentType().isBlank()
? MediaType.APPLICATION_JSON
: MediaType.parseMediaType(api.contentType());
}
private <R> R convertResponse(HttpBody responseBody, Class<R> responseBodyClass) {
String content = responseBody == null ? null : responseBody.content();
if (responseBodyClass == String.class) {
return responseBodyClass.cast(content);
}
try {
return json.readValue(content, responseBodyClass);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Failed to convert HTTP response to " + responseBodyClass.getSimpleName(), e);
}
}
private void putIfPresent(HttpHeader header, String name, String value) {
if (value != null && !value.isBlank()) {
header.set(name, value);
}
}
private String joinPath(String configuredUrl, String suffix) {
String left = configuredUrl == null ? "" : configuredUrl.replaceAll("/+$", "");
if (suffix == null || suffix.isBlank()) {
return left.isEmpty() ? "/" : left;
}
String right = suffix.startsWith("/") ? suffix : "/" + suffix;
return left + right;
}
}

View File

@@ -1,34 +0,0 @@
package io.shinhanlife.dap.lib.integration.http.component;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
/**
* Glow HTTP target catalog.
*
* <p>Each target follows the ShinhanLife standard: name, domain, url, method,
* content-type, and biz-pod. Target-specific values belong in application-glow*.yml.</p>
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "glow.communication.http")
public class AxhubHttpProperties {
private List<ApiDefinition> apiList = new ArrayList<>();
public record ApiDefinition(
String name,
String domain,
String url,
HttpMethod method,
String contentType,
boolean bizPod
) {
}
}

Some files were not shown because too many files have changed in this diff Show More