Files
dap-was-dapmt/README.md
jade 740ef1c757
All checks were successful
Deploy Tools / deploy (push) Successful in 1m11s
refactor: rename dasmt to datmt across the project
2026-08-31 13:21:33 +09:00

477 lines
27 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DATMT MCP Tool Pods
?좏븳?쇱씠???낅Т 湲곕뒫??MCP(Model Context Protocol) Tool濡??쒓났?섎뒗 Java 硫€??紐⑤뱢 ?꾨줈?앺듃?낅땲?? 媛??낅Т 紐⑤뱢?€ ?낅┰ ?ㅽ뻾 媛€?ν븳 Spring Boot ?좏뵆由ъ??댁뀡?대ʼn, MCP Streamable HTTP?€ REST ?ㅽ뻾 API瑜??④퍡 ?쒓났?⑸땲??
???€?μ냼?먮뒗 DATMS(Gateway) ?좏뵆由ъ??댁뀡???ы븿?섏뼱 ?덉? ?딆뒿?덈떎. DATMT??Gateway濡?Tool??push ?깅줉?섏? ?딆쑝硫? 媛?Pod媛€ `GET /tool-manifest`瑜??쒓났?섎㈃ DATMS媛€ ??Manifest瑜?pull?섏뿬 Tool 紐⑸줉??援ъ꽦?⑸땲?? Tool 議고쉶?€ 吏곸젒 ?ㅽ뻾?€ 媛?Pod?먯꽌???먯껜?곸쑝濡?泥섎━?⑸땲??
## 湲곗닠 湲곗?
- 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.19.4 (Spring Boot BOM)
- MapStruct, MyBatis, Redis, Kafka, Resilience4j
- JUnit 5
## 紐⑤뱢 援ъ꽦
| 紐⑤뱢 | ??븷 | 湲곕낯 ?ы듃 | Tool ??|
|---|---|---:|---:|
| `dat-was-lib` | MCP ?쒕쾭, Tool ?ㅼ틪쨌?ㅽ뻾, Schema, Manifest, 蹂댁븞, MCI/EAI/HTTP ?곕룞 怨듯넻 湲곕뒫 | - | - |
| `dat-was-cus` | 怨좉컼쨌CRM쨌VOC쨌??肄섑뀗痢?愿€由?Tool | 8084 | 51 |
| `dat-was-sal` | ?곸뾽쨌泥?뎄쨌?몄닔쨌?숈쓽쨌?꾩옣吏€??Tool | 8082 | 52 |
| `dat-was-pro` | ?곹뭹 ?곸뿭 Tool(媛쒖씤怨좉컼 ?곸꽭議고쉶쨌紐⑥쭛?섏닔猷?怨듭떆) | 8085 | 2 |
| `dat-was-sys` | IAM쨌?쒖뒪???곹깭쨌怨듭?쨌?먭?쨌諛고룷 Tool | 8086 | 51 |
?낅Т 紐⑤뱢?먮뒗 珥?156媛쒖쓽 `@McpTool` ?좎뼵???덉뒿?덈떎. ?꾩옱 ?낅Т 紐⑤뱢??`src/main/resources`?먮뒗 蹂꾨룄 `tool-definitions` YAML???놁쑝硫? Tool 硫뷀??곗씠?곕뒗 ?대끂?뚯씠?섍낵 `@GrowToolHint`瑜?湲곗??쇰줈 ?앹꽦?⑸땲??
?꾩옱 ?낅Т 援ы쁽?€ 媛쒕컻쨌?곕룞 寃€利??④퀎?낅땲?? `dat-was-sal`??`cmm_claim_search`?€ `cmm_memo_retriever`??媛곴컖 MCI?€ HTTP Client ?먮쫫???ъ슜?섎ʼn, ?섎㉧吏€ 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
?? ?붴? DATMS媛€ 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`瑜??듯빐 ?ㅽ뻾?⑸땲??
DATMT ?대??먮뒗 `/registry/register`, `/registry/deregister` ?몄텧?대굹 二쇨린?곸씤 Gateway heartbeat ?꾩넚???놁뒿?덈떎. `ToolRegistryHeartbeatSender`?쇰뒗 ?대옒?ㅻ챸?€ ?명솚?깆쓣 ?꾪빐 ?⑥븘 ?덉?留??꾩옱 ??븷?€ 濡쒖뺄 Tool ?ㅼ틪怨?硫뷀??곗씠???앹꽦肉먯엯?덈떎.
### DATMS ?곕룞 諛⑹떇
```text
DATMS
?붴? GET {DATMT 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`?낅땲??
- DATMS???ㅼ젙??bundle ID?€ DATMT媛€ 諛섑솚?섎뒗 `bundleId`媛€ ?쇱튂?댁빞 媛숈? Tool bundle濡?愿€由щ맗?덈떎.
- `mcp.manifest.name-prefix`媛€ 鍮꾩뼱 ?덉? ?딆쑝硫?紐⑤뱺 Tool ?대쫫???대떦 prefix濡??쒖옉?댁빞 ?⑸땲??
- Manifest ?댁슜??諛붾€뚮㈃ `revision`??利앷??섎ʼn, `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` |
| 移댄뀒怨좊━蹂?Tool Manifest 議고쉶 | `GET` | `/tool-manifest/{categoryKey}` |
`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
'X-Guid' = 'guid-local-001'
'X-Praf-No' = '100001'
'X-Request-Id' = 'request-local-001'
'X-Request-Time' = '2026-08-25T12:34:56+09:00'
'X-Vrtl-Praf-No' = 'V100001'
'X-App-Code' = 'DATMT'
'X-Project-Code' = 'AXHUB'
'X-User-Ip' = '10.0.0.10'
'X-Caller-Ip' = '10.0.0.20'
'X-Caller-Host' = 'caller.example.internal'
'X-Channel' = 'MCP'
'X-Agent-Id' = 'agent-local-001'
'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":"媛쒕컻"}'
```
### ?붿껌 ?ㅻ뜑 怨꾩빟
DATMS媛€ DATMT Tool Service瑜??몄텧?????ъ슜?섎뒗 ?ㅻ뜑???ㅼ쓬怨?媛숈뒿?덈떎. HTTP ?ㅻ뜑 ?대쫫?€ ?€?뚮Ц?먮? 援щ텇?섏? ?딆?留? 臾몄꽌?€ 援ы쁽?먯꽌???꾨옒 ?쒓린瑜?湲곗??쇰줈 ?ъ슜?⑸땲??
| ?ㅻ뜑 | ?꾩닔 ?щ? | ?⑸룄 | ?꾨떖 ?숈옉 |
|---|---|---|---|
| `X-Tool-Server-API-Key` | ?몄쬆 ?ㅼ젙 ???꾩닔 | DATMS?€ DATMT ?ъ씠??Tool Server ?몄쬆 | `mcp.security.api-key` ?먮뒗 `api-keys`?€ 鍮꾧탳 |
| `X-Guid` | ?좏깮 | ?낅Т ?몄텧 ?곴?愿€怨??앸퀎??| ?ㅽ뻾 濡쒓렇, ?깃났 ?묐떟, ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Praf-No` | ?좏깮 | ?ㅼ젣 ?ъ슜???щ쾲 | ?몄뀡 議고쉶?€ ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Request-Id` | ?좏깮 | ?붿껌 異붿쟻 ?앸퀎??| ?ㅽ뻾 濡쒓렇, ?깃났 ?묐떟, ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Request-Time` | ?좏깮 | ?붿껌 諛쒖깮 ?쒓컖 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Vrtl-Praf-No` | ?좏깮 | 媛€???ъ슜???щ쾲 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-App-Code` | ?좏깮 | ?몄텧 ?좏뵆由ъ??댁뀡 肄붾뱶 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Project-Code` | ?좏깮 | ?몄텧 ?꾨줈?앺듃 肄붾뱶 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-User-Ip` | ?좏깮 | ?ъ슜??IP 二쇱냼 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Caller-Ip` | ?좏깮 | ?몄텧 ?쒖뒪??IP 二쇱냼 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Caller-Host` | ?좏깮 | ?몄텧 ?쒖뒪???몄뒪?몃챸 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Channel` | ?좏깮 | ?몄텧 梨꾨꼸 | ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `X-Agent-Id` | ?좏깮 | ?몄텧 Agent ?앸퀎??| ?섏쐞 HTTP ?몄텧濡??꾨떖 |
| `mcp-session-id` | ?좏깮 | MCP ?몄뀡 ?앸퀎??| ?깃났 ?묐떟怨??섏쐞 HTTP ?몄텧濡??꾨떖 |
`McpRequestHeaderFilter`??URI??`/mcp`媛€ ?ы븿???붿껌?먯꽌 ???ㅻ뜑瑜?`McpRequestHeaderContext`???€?ν븯誘€濡?REST `/mcp/{toolName}`怨?MCP Streamable HTTP `/mcp`, `/mcp/message`??紐⑤몢 ?곸슜?⑸땲?? REST 寃쎈줈??`BusinessToolController`???숈씪???ㅻ뜑瑜?吏곸젒 ?쎌뼱 ?ㅽ뻾 ?쒕퉬?ㅼ뿉 ?꾨떖?⑸땲?? ?ㅻ뜑媛€ ?녿뒗 ?섏쐞 HTTP ?몄텧?먮뒗 `X-ANONYMOUS-REQ: AXHUB-TOOL`???ㅼ젙?⑸땲??
湲곗〈 `guid`, `employee-no`, `virtual-employee-no` ?ㅻ뜑??吏€?먰븯吏€ ?딆뒿?덈떎.
二쇱슂 ?ㅽ뻾 ?묐떟?€ ?ㅼ쓬怨?媛숈뒿?덈떎.
| 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` Gradle ?묒뾽?쇰줈 寃€?ы빀?덈떎. ?꾩옱 猷⑦듃 `build.gradle`?먮뒗 `validateToolSchemaV17` Gradle ?묒뾽???깅줉?섏뼱 ?덉? ?딆쑝硫? 紐⑤뱺 `bootJar` ?묒뾽?€ `validateMcpToolNames`?먮쭔 ?섏〈?⑸땲??
## Tool YAML ?뺤쓽
怨듯넻 ?쇱씠釉뚮윭由щ뒗 Tool 硫뷀??곗씠?곕? 蹂닿컯?섍린 ?꾪븳 ?좏깮??YAML ?뺤쓽瑜?吏€?먰빀?덈떎. YAML ?뺤쓽瑜?異붽???寃쎌슦 ?낅Т 紐⑤뱢???ㅼ쓬 寃쎈줈瑜??ъ슜?⑸땲??
```text
dat-was-*/src/main/resources/tool-definitions/{category}/{tool-name}.yml
```
?꾩옱 ?낅Т 紐⑤뱢?먮뒗 ??寃쎈줈??YAML ?뺤쓽媛€ ?놁뒿?덈떎. ?곕씪???ㅽ뻾 ??硫뷀??곗씠?곕뒗 `@McpTool`, `@GrowToolHint`, DTO Schema瑜?湲곗??쇰줈 援ъ꽦?⑸땲?? YAML ?뺤쓽瑜??꾩엯?섎뒗 寃쎌슦 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瑜??댁꽍?⑸땲?? YAML ?뺤쓽媛€ ?덉쑝硫?`ToolRegistryHeartbeatSender`媛€ `parameters_schema`?€ `output_schema`瑜?蹂묓빀?섏뿬 理쒖쥌 硫뷀??곗씠?곕? 留뚮벊?덈떎.
?ㅽ뻾 ??Schema 寃€利앹? MCP Java SDK??`DefaultJsonSchemaValidator`瑜??ъ슜?섎ʼn 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`媛€ ?ъ슜?⑸땲?? ?댁쁺 ?섍꼍?먯꽌??湲곕낯媛믪쓣 ?ъ슜?섏? 留먭퀬 DATMS??Tool Server API Key?€ ?숈씪??蹂꾨룄 Secret??二쇱엯?댁빞 ?⑸땲??
媛?Pod??蹂꾨룄 ?곕??먯뿉???ㅽ뻾?⑸땲??
```powershell
# ?곸뾽 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8082'
.\gradlew.bat :dat-was-sal:bootRun
# 怨좉컼 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8084'
.\gradlew.bat :dat-was-cus:bootRun
# ?곹뭹 Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8085'
.\gradlew.bat :dat-was-pro:bootRun
# ?쒖뒪??Tool Pod
$env:AXHUB_TOOL_URL = 'http://localhost:8086'
.\gradlew.bat :dat-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` | DATMS媛€ `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. ?꾩옱 DATMT??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`???⑥씪 DATMS 怨듯넻 Key瑜? `mcp.security.api-keys`??`API Key ??tenant ID` ?뺥깭???ㅼ쨷 Key瑜?吏€?먰빀?덈떎. `ApiKeyInterceptor`??Spring MVC媛€ 泥섎━?섎뒗 `/rpc/**`, `/mcp/**` ?붿껌???곸슜?섎?濡?REST `/mcp/{toolName}`怨?`/mcp/api/v1/tools/local`?€ ?щ컮瑜?`X-Tool-Server-API-Key`媛€ ?놁쑝硫?`401 Unauthorized`媛€ ?⑸땲?? ???ㅼ젙??紐⑤몢 鍮꾩뼱 ?덉쓣 ?뚮뒗 ?대떦 MVC ?붿껌???듬챸?쇰줈 ?덉슜?⑸땲?? ?꾩옱 ???낅Т Pod??湲곕낯 `application.yml`?€ ?⑥씪 Key瑜??ㅼ젙?⑸땲??
諛섎㈃ `/mcp`?€ `/mcp/message`??蹂꾨룄 Servlet?쇰줈 ?깅줉?섏뼱 Spring MVC `HandlerInterceptor`瑜??듦낵?섏? ?딆뒿?덈떎. ?꾩옱 援ы쁽留뚯쑝濡쒕뒗 ????MCP Streamable HTTP 寃쎈줈??`ApiKeyInterceptor` ?몄쬆???곸슜?섏? ?딆쑝誘€濡? ?댁쁺 諛고룷 ??Servlet Filter ?먮뒗 ?꾩슜 MCP ?몄쬆 怨꾩링??異붽??댁빞 ?⑸땲??
## 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`瑜??낅젰?섎㈃ `dat-was-payment` 紐⑤뱢???앹꽦?⑸땲?? ?앹꽦?섎뒗 `application.yml`?먮뒗 ?ㅼ쓬 怨꾩빟???ы븿?⑸땲??
```yaml
mcp:
manifest:
bundle-id: dat-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`瑜?DATMS???깅줉??bundle ID?€ ?쇱튂?쒗궢?덈떎.
2. ?댁쁺 ?섍꼍??`TOOL_SERVER_API_KEY`瑜?DATMS媛€ ?꾨떖?섎뒗 Key?€ ?숈씪??Secret?쇰줈 ?ㅼ젙?⑸땲??
3. ?ㅼ젣 諛고룷 二쇱냼??留욊쾶 `AXHUB_TOOL_URL`???ㅼ젙?⑸땲??
4. MCI쨌EAI쨌HTTP ?곕룞 ?€?곴낵 timeout???섍꼍蹂??ㅼ젙?쇰줈 援먯껜?⑸땲??
5. `validateMcpToolNames`?€ 紐⑤뱢쨌?꾩껜 ?뚯뒪?몃? ?ㅽ뻾?⑸땲?? YAML ?뺤쓽瑜?異붽??덈떎硫?`ToolSchemaV17ValidationRunner` ?먮뒗 愿€???뚯뒪?몃줈 V17 ??ぉ??蹂꾨룄 寃€利앺빀?덈떎.
## ?뚯뒪?몄? 寃€利?
```powershell
# ?댁쁺 ?뚯뒪 ?꾩껜 而댄뙆??
.\gradlew.bat classes
# ?꾩껜 ?뚯뒪??
.\gradlew.bat test
# 紐⑤뱢蹂??뚯뒪??
.\gradlew.bat :dat-was-lib:test
.\gradlew.bat :dat-was-cus:test
.\gradlew.bat :dat-was-sal:test
.\gradlew.bat :dat-was-pro:test
.\gradlew.bat :dat-was-sys:test
# Tool ?대쫫쨌以묐났 寃€??
.\gradlew.bat validateMcpToolNames
# 寃€利? ?뚯뒪?? ?⑦궎吏?
.\gradlew.bat clean build
```
### ?ㅽ뻾 ???뺤씤
?뚯뒪???섏? ?깃났 ?щ????뚯뒪 蹂€寃쎌뿉 ?곕씪 ?щ씪吏€誘€濡?怨좎젙???섏튂瑜?臾몄꽌?뷀븯吏€ ?딆뒿?덈떎. 諛고룷 ???꾩옱 ?묒뾽 ?몃━?먯꽌 ?ㅼ쓬 紐낅졊???ㅽ뻾???뺤씤?⑸땲??
```powershell
.\gradlew.bat test validateMcpToolNames
```
## Docker Compose
`docker-compose.yml`?€ DATMT?????낅Т 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 :dat-was-sal:bootJar :dat-was-cus:bootJar :dat-was-pro:bootJar :dat-was-sys:bootJar
docker compose up --build
```
Compose ?뚯씪???⑸룄?€ ?꾩옱 二쇱쓽?먯? ?ㅼ쓬怨?媛숈뒿?덈떎.
| ?뚯씪 | ?⑸룄 | ?꾩옱 ?뚯뒪 湲곗? 二쇱쓽??|
|---|---|---|
| `docker-compose.yml` | DATMT ??Pod ?⑤룆 ?ㅽ뻾 | `gateway` ?쒕퉬?ㅺ? ?놁?留?push ?깅줉???쒓굅?섏뼱 DATMT ?쒖옉?먮뒗 ?꾩슂?섏? ?딆쓬 |
| `docker-compose.local.yml` | DATMS?€ DATMT??濡쒖뺄 ?듯빀 援ъ꽦 | ???€?μ냼媛€ 媛숈? ?곸쐞 ?붾젆?곕━???덈뒗 援ъ“瑜?媛€??|
| `docker-compose.prod.yml` | DATMS?€ DATMT??媛쒕컻 ?꾨줈??湲곕컲 OCI 援ъ꽦 | ?€?μ냼??runner ?깅줉 ?좏겙???댁쁺 Secret?쇰줈 遺꾨━?댁빞 ??|
`docker-compose.local.yml`怨?`docker-compose.prod.yml`??build context??媛곴컖 `./dat-was-DATMS`, `./dat-was-datmt`?낅땲?? ?꾩옱 ?뚯씪 ?꾩튂?먯꽌 ?ъ슜???뚮뒗 context 湲곗??????€?μ냼???곸쐞 ?붾젆?곕━濡?留욎떠???⑸땲??
```powershell
# DATMT ?€?μ냼 ?붾젆?곕━?먯꽌 ?ㅽ뻾
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` ?꾨떖 ?ㅼ젙??異붽??섍퀬 DATMS??Key?€ ?쇱튂?쒖폒???⑸땲?? DATMS??媛?Pod??`AXHUB_TOOL_URL` ?먮뒗 諛고룷 URL???묎렐??`/tool-manifest`瑜?pull?????덉뼱???⑸땲??
## OpenShift (Kubernetes) 諛고룷
OpenShift 媛쒕컻 ?섍꼍??Kustomize 留ㅻ땲?섏뒪?몃뒗 [`k8s/`](k8s/)???덉뒿?덈떎. ?€?곸? DATMT????Tool Pod肉먯씠硫?DATMS(Gateway)??Deployment쨌Service쨌Route?????€?μ냼?먯꽌 留뚮뱾吏€ ?딆뒿?덈떎.
```text
k8s/
?쒋? base/ # ??Pod 怨듯넻 ConfigMap, Service, Deployment
?붴? overlays/dev/ # 媛쒕컻 namespace, Registry ?대?吏€ 寃쎈줈?€ tag
```
### 諛고룷 援ъ“
媛?Tool Pod??Deployment 1媛쒖? ?몃????몄텧?섏? ?딅뒗 `ClusterIP` Service 1媛쒕? ?ъ슜?⑸땲?? OpenShift Route?€ LoadBalancer Service???앹꽦?섏? ?딆쑝硫? Gateway媛€ ?대윭?ㅽ꽣 ?대? DNS濡??몄텧?⑸땲??
| Service | Pod ?ы듃 | Gateway ?몄텧 二쇱냼 |
|---|---:|---|
| `was-sal` | 8082 | `http://was-sal:8082` |
| `was-cus` | 8084 | `http://was-cus:8084` |
| `was-pro` | 8085 | `http://was-pro:8085` |
| `was-sys` | 8086 | `http://was-sys:8086` |
Gateway媛€ ?ㅻⅨ namespace???덉쑝硫?`was-sal.axhub-datmt-dev.svc`?€ 媛숈? FQDN???ъ슜?섍퀬, NetworkPolicy?먯꽌 Gateway namespace??ingress瑜?蹂꾨룄濡??덉슜?댁빞 ?⑸땲??
### 諛섏쁺 ???ㅼ젙
?ㅼ쓬 媛믪? ?ㅼ젣 ?좏븳?쇱씠??媛쒕컻留?媛믪쑝濡?援먯껜?댁빞 ?⑸땲??
1. [`k8s/overlays/dev/kustomization.yaml`](k8s/overlays/dev/kustomization.yaml)??namespace, ?대? Container Registry 寃쎈줈, 諛고룷 image tag
2. [`k8s/base/configmap.yaml`](k8s/base/configmap.yaml)??`CHANGE_ME` MCI쨌EXTMCI쨌EAI ?몄뒪??
3. ?ㅼ젣 Secret 媛?
`datmt-runtime-secrets` Secret?€ Git???€?ν븯吏€ ?딄퀬 OpenShift namespace?먯꽌 蹂꾨룄濡??앹꽦?⑸땲?? 理쒖냼??`TOOL_SERVER_API_KEY`??DATMS媛€ ?꾨떖?섎뒗 `X-Tool-Server-API-Key`?€ 媛숈? 媛믪씠?댁빞 ?⑸땲?? DB 怨꾩젙쨌鍮꾨?踰덊샇, API Key, ?몄쬆??鍮꾨?踰덊샇 ?깅룄 ??Secret?쇰줈 愿€由ы빀?덈떎.
```powershell
# runtime-secrets.env???€?μ냼 諛뽰뿉 蹂닿??⑸땲??
oc -n axhub-datmt-dev create secret generic datmt-runtime-secrets `
--from-env-file=runtime-secrets.env
```
Secret???놁쑝硫?媛?Deployment??`envFrom.secretRef`瑜??댁꽍?????놁뼱 Pod媛€ ?쒖옉?섏? ?딆쓣 ???덉뒿?덈떎.
### ?대?吏€ 鍮뚮뱶?€ 諛고룷
紐⑤뱢 Dockerfile?€ 誘몃━ ?앹꽦??Boot JAR瑜?蹂듭궗?섎?濡? ?대?吏€瑜?留뚮뱾湲??꾩뿉 ??紐⑤뱢??JAR瑜?鍮뚮뱶?⑸땲?? 媛쒕컻留앹뿉?쒕뒗 JDK/JRE 踰좎씠???대?吏€?€ Gradle/Maven ?섏〈?깆쓣 ?대? Registry쨌Nexus?먯꽌 ?ъ슜?????덉뼱???⑸땲??
```powershell
.\gradlew.bat :dat-was-sal:bootJar :dat-was-cus:bootJar :dat-was-pro:bootJar :dat-was-sys:bootJar
# OpenShift 濡쒓렇??諛?project ?좏깮 ??
oc kustomize k8s/overlays/dev
oc apply -k k8s/overlays/dev
oc get deployment,pod,svc -n axhub-datmt-dev
```
?곸슜 ?꾩뿉??`oc kustomize k8s/overlays/dev | oc apply --dry-run=client -f -`濡??쒕쾭 痢??ㅽ궎留?寃€利앹쓣 ?섑뻾?⑸땲?? ?꾩옱 留ㅻ땲?섏뒪?몄쓽 readiness/liveness probe??TCP ?ы듃 ?뺤씤 諛⑹떇?낅땲?? Actuator health endpoint瑜?異붽????ㅼ뿉??HTTP readiness/liveness probe濡?蹂€寃쏀븯??寃껋쓣 沅뚯옣?⑸땲??
?곸꽭??紐낅졊怨?Gateway ?곌껐 ?뺤씤 諛⑸쾿?€ [`k8s/README.md`](k8s/README.md)瑜?李멸퀬?⑸땲??
## 蹂댁븞 諛??댁쁺 二쇱쓽?ы빆
?꾩옱 援ы쁽???댁쁺 ?섍꼍???몄텧?섍린 ?꾩뿉 ?꾨옒 ??ぉ??諛섎뱶???먭??댁빞 ?⑸땲??
- API Key ?명꽣?됲꽣??Spring MVC??`/rpc/**`, `/mcp/**` Handler???곸슜?⑸땲?? REST `/mcp/{toolName}`怨?`/mcp/api/v1/tools/local`?€ ?몄쬆 ?€?곸엯?덈떎.
- 蹂꾨룄 Servlet??`/mcp`, `/mcp/message`??MVC ?명꽣?됲꽣瑜??고쉶?섎?濡??꾩옱 API Key ?몄쬆 ?€?곸씠 ?꾨떃?덈떎. ?댁쁺 ?몄텧 ?꾩뿉 蹂꾨룄 ?몄쬆??異붽??댁빞 ?⑸땲??
- `/tool-manifest`?€ `/tool-manifest/{categoryKey}`?????명꽣?됲꽣 寃쎈줈 諛뽰뿉 ?덉뼱 ?꾩옱 API Key ?몄쬆 ?€?곸씠 ?꾨떃?덈떎. ?대?留씲텶ngress ?뺤콉 ?먮뒗 蹂꾨룄 ?몄쬆???꾩슂?쒖? ?댁쁺 湲곗????뺤씤?댁빞 ?⑸땲??
- ???낅Т Pod??湲곕낯 Key??紐⑤몢 `tool-server-key`?낅땲?? ?댁쁺?먯꽌??諛섎뱶??蹂꾨룄 Secret?쇰줈 援먯껜?섍퀬 DATMS??`X-Tool-Server-API-Key` 媛믨낵 ?쇱튂?쒖폒???⑸땲??
- ?ㅼ젙???⑥씪 Key?€ ?ㅼ쨷 Key媛€ 紐⑤몢 ?놁쓣 ?뚮쭔 ?듬챸 ?붿껌???덉슜?⑸땲??
- `mcp.security.tenant-domains`???ㅼ젙 媛앹껜??諛붿씤?⑸릺吏€留?Tool蹂??멸????ъ슜?섏? ?딆뒿?덈떎.
- `requiresApproval`?€ 硫뷀??곗씠?곗뿉留?湲곕줉?섎ʼn ?ㅽ뻾 李⑤떒?대굹 ?뱀씤 ?뺤씤 濡쒖쭅?€ ?놁뒿?덈떎.
- ?낅젰쨌異쒕젰 Schema 泥섎━ ?먯껜?먯꽌 ?덉쇅媛€ 諛쒖깮?섎㈃ ?꾩옱 ?ㅽ뻾 ?쒕퉬?ㅻ뒗 濡쒓렇瑜??④린怨?寃€利앹쓣 嫄대꼫?곷땲??
- CORS??紐⑤뱺 Origin???덉슜?섎㈃??credential???덉슜?섎룄濡??ㅼ젙?섏뼱 ?덉뒿?덈떎. ?댁쁺 Origin??紐낆떆?곸쑝濡??쒗븳?댁빞 ?⑸땲??
- `docker-compose.prod.yml`??runner ?깅줉 ?좏겙???됰Ц?쇰줈 ?ы븿?섏뼱 ?덉뒿?덈떎. ?ъ슜 以묒씤 ?좏겙?€ ?먭린쨌?щ컻湲됲븯怨?諛고룷 Secret?쇰줈 ?댁쟾?댁빞 ?⑸땲??
- Tool ?붿껌怨??곕룞 ?ㅻ쪟 濡쒓렇??媛쒖씤?뺣낫???몄쬆?뺣낫媛€ ?ы븿?섏? ?딅룄濡?DTO?€ 濡쒓렇 留덉뒪???뺤콉??寃€?좏빐???⑸땲??
## 二쇱슂 ?뚯뒪 ?꾩튂
| 二쇱젣 | ?꾩튂 |
|---|---|
| 怨듯넻 鍮뚮뱶 諛?寃€利??묒뾽 | `build.gradle` |
| REST Tool ?ㅽ뻾 API | `dat-was-lib/src/main/java/io/shinhanlife/dat/mcc/presentation/BusinessToolController.java` |
| ?붿껌 ?ㅻ뜑 罹≪쿂쨌?꾨떖 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/McpRequestHeaderFilter.java`, `McpRequestHeaderContext.java` |
| Tool ?ㅽ뻾 ?쒕퉬??| `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/McpToolExecutionService.java` |
| JSON Schema 2020-12 寃€利??ㅼ젙 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/config/ToolSchemaConfiguration.java` |
| ?ㅽ뻾 硫붿꽌??Registry | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/McpToolMethodRegistry.java` |
| MCP SDK ?쒕쾭 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/ToolMcpServerConfiguration.java` |
| MCP Tool ?숆린??| `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/ToolPodMcpToolSynchronizer.java` |
| Tool ?ㅼ틪 諛?硫뷀??곗씠???앹꽦 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/ToolRegistryHeartbeatSender.java` |
| YAML Tool ?뺤쓽 濡쒕뵫 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/metadata/ToolDefinitionRepository.java` |
| V17 ?뺤쓽 寃€利?| `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/metadata/ToolDefinitionValidator.java` |
| Manifest ?앹꽦 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/manifest/ToolManifestService.java` |
| API Key ?명꽣?됲꽣 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/mcp/security/ApiKeyInterceptor.java` |
| Tool쨌Pod ?ㅼ틦?대뵫 | `dat-was-lib/src/main/java/io/shinhanlife/dat/lib/util/ToolScaffolder.java`, `PodScaffolder.java` |
## 媛쒕컻 ??沅뚯옣 ?뺤씤 ?쒖꽌
1. Tool 硫붿꽌?쒖? ?붿껌쨌?묐떟 DTO瑜?援ы쁽?⑸땲??
2. ?숈씪 ?대쫫??V17 YAML ?뺤쓽瑜?`tool-definitions` ?꾨옒??異붽??⑸땲??
3. `validateMcpToolNames`?€ 紐⑤뱢쨌?꾩껜 ?뚯뒪?몃? ?ㅽ뻾?⑸땲?? Tool YAML ?뺤쓽瑜?異붽???寃쎌슦?먮뒗 V17 ??ぉ??蹂꾨룄 寃€利앺빀?덈떎.
4. 紐⑤뱢 ?뚯뒪?몄? ?꾩껜 ?뚯뒪?몃? ?ㅽ뻾?⑸땲??
5. 濡쒖뺄 Pod?먯꽌 `/mcp/api/v1/tools/local`怨?`/tool-manifest`瑜??뺤씤?⑸땲??
6. DATMS??bundle ID, Pod Manifest URL, Tool Server API Key媛€ DATMT ?ㅼ젙怨??쇱튂?섎뒗吏€ ?뺤씤?⑸땲??
7. REST?€ MCP ?묒そ?먯꽌 ?숈씪??Tool 寃곌낵쨌?붿껌 ?ㅻ뜑 ?꾨떖쨌?ㅻ쪟 怨꾩빟???뺤씤?⑸땲??