From 97cd5c9f251cb5a2a44dc8c3ca68ace7f0ca0ebf Mon Sep 17 00:00:00 2001 From: devmrko Date: Mon, 27 Jul 2026 13:51:56 +0900 Subject: [PATCH] add game catalog resolver MCP tool --- .../vpdbackoffice/service/McpSseService.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java b/src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java index b2c3a09..29d284a 100644 --- a/src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java +++ b/src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Service; public class McpSseService { private static final String SELECT_AI_TOOL_PATH = "/mcp (tools/call)"; + private static final String GAME_CATALOG_TOOL = "oracle.select_ai.game_catalog_resolve"; private final SelectAiService selectAiService; private final ObjectMapper objectMapper; @@ -77,7 +78,7 @@ public class McpSseService { public List registeredTools() { return List.of( selectAiQueryView(), selectAiShowpromptView(), qaVectorSearchView(), - qaVectorStoreView(), fewShotNl2SqlView(), gameScopeView()); + qaVectorStoreView(), fewShotNl2SqlView(), gameScopeView(), gameCatalogView()); } private ObjectNode initializeResult(String contextPath) { @@ -102,6 +103,7 @@ public class McpSseService { tools.add(toolDefinition(qaVectorStoreView())); tools.add(toolDefinition(fewShotNl2SqlView())); tools.add(toolDefinition(gameScopeView())); + tools.add(toolDefinition(gameCatalogView())); result.set("tools", tools); return result; } @@ -116,7 +118,8 @@ public class McpSseService { ObjectNode properties = objectMapper.createObjectNode(); ArrayNode required = objectMapper.createArrayNode(); - if (qaVectorSearchToolName().equals(toolView.name()) || gameScopeToolName().equals(toolView.name())) { + if (qaVectorSearchToolName().equals(toolView.name()) || gameScopeToolName().equals(toolView.name()) + || GAME_CATALOG_TOOL.equals(toolView.name())) { addStringProperty(properties, "question", "few-shot 예제 SQL을 찾을 현재 질문입니다.", 4000); ObjectNode topK = properties.putObject("topK"); topK.put("type", "integer"); @@ -161,8 +164,9 @@ public class McpSseService { boolean qaVectorStoreTool = qaVectorStoreToolName().equals(calledToolName); boolean fewShotNl2SqlTool = fewShotNl2SqlToolName().equals(calledToolName); boolean gameScopeTool = gameScopeToolName().equals(calledToolName); + boolean gameCatalogTool = GAME_CATALOG_TOOL.equals(calledToolName); if (!queryTool && !showpromptTool && !qaVectorSearchTool && !qaVectorStoreTool && !fewShotNl2SqlTool - && !gameScopeTool) { + && !gameScopeTool && !gameCatalogTool) { throw new AppException("등록되지 않은 MCP tool입니다: " + calledToolName); } @@ -186,6 +190,9 @@ public class McpSseService { } else if (gameScopeTool) { response = gameScopeResponse(gameScopeService.resolve( token, arguments.path("question").asText(""))); + } else if (gameCatalogTool) { + response = gameScopeResponse(gameScopeService.resolve( + token, arguments.path("question").asText(""))); } else { String prompt = arguments.path("prompt").asText(""); response = queryTool @@ -331,6 +338,13 @@ public class McpSseService { gameScopeToolLabel(), SELECT_AI_TOOL_PATH); } + private McpToolView gameCatalogView() { + return new McpToolView( + GAME_CATALOG_TOOL, + "게임 카탈로그에서 질문의 게임 범위를 확인합니다. SQL은 실행하지 않습니다.", + -1L, "게임 카탈로그 범위 확인", SELECT_AI_TOOL_PATH); + } + private String selectAiProfile() { BackofficeProperties.SelectAi selectAi = properties == null ? null : properties.selectAi(); if (selectAi == null || selectAi.profile() == null || selectAi.profile().isBlank()) {