# 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 [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 寃곌낵쨌?붿껌 ?ㅻ뜑 ?꾨떖쨌?ㅻ쪟 怨꾩빟???뺤씤?⑸땲??