diff --git a/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/McpRouterController.java b/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/McpRouterController.java index fb7608db..228c4b61 100644 --- a/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/McpRouterController.java +++ b/dap-gateway/src/main/java/io/shinhanlife/dap/mcg/presentation/McpRouterController.java @@ -192,7 +192,9 @@ public class McpRouterController { meta.put("owner_org", t.getOwnerOrg()); meta.put("legacy_interface_id", t.getMciServiceId()); meta.put("display_description", t.getDisplayDescription()); - meta.put("example_queries", t.getExampleQueries()); + meta.put("when_to_use", t.getWhenToUse()); + meta.put("when_not_to_use", t.getWhenNotToUse()); + meta.put("io_limits", t.getIoLimits()); meta.put("example_queries", t.getExampleQueries()); meta.put("required_env_keys", t.getRequiredEnvKeys()); diff --git a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapper.java b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapper.java index 8624e60e..96bab93a 100644 --- a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapper.java +++ b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapper.java @@ -32,6 +32,9 @@ public final class ToolMetadataMcpMapper { put(meta, "version", metadata.getSemver()); put(meta, "category_key", metadata.getCategoryKey()); put(meta, "display_description", metadata.getDisplayDescription()); + put(meta, "when_to_use", metadata.getWhenToUse()); + put(meta, "when_not_to_use", metadata.getWhenNotToUse()); + put(meta, "io_limits", metadata.getIoLimits()); put(meta, "example_queries", metadata.getExampleQueries()); put(meta, "tags", metadata.getTags()); put(meta, "legacy_interface_id", metadata.getMciServiceId()); diff --git a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java index 1e79f37a..8ff02755 100644 --- a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java +++ b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java @@ -207,10 +207,7 @@ public class ToolRegistryHeartbeatSender { meta.setWhenToUse(definition.description().whenToUse()); meta.setWhenNotToUse(definition.description().whenNotToUse()); meta.setIoLimits(definition.description().ioLimits()); - meta.setDescription(String.join("\n", definition.description().function(), - "사용 시점: " + definition.description().whenToUse(), - "사용 제외: " + definition.description().whenNotToUse(), - "입출력 제한: " + definition.description().ioLimits())); + meta.setDescription(definition.description().function()); meta.setDisplayDescription(definition.displayDescription()); meta.setExampleQueries(definition.exampleQueries()); meta.setReadOnlyHint(definition.readOnly()); diff --git a/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapperTest.java b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapperTest.java new file mode 100644 index 00000000..aca89718 --- /dev/null +++ b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolMetadataMcpMapperTest.java @@ -0,0 +1,21 @@ +package io.shinhanlife.dap.lib.mcp; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.shinhanlife.dap.mcc.dto.ToolMetadata; +import org.junit.jupiter.api.Test; + +class ToolMetadataMcpMapperTest { + + @Test + void includesUsageGuidanceInMcpMeta() { + ToolMetadata metadata = new ToolMetadata(); + metadata.setWhenToUse("사용 시점"); + metadata.setWhenNotToUse("사용 제외"); + metadata.setIoLimits("입출력 제한"); + + assertThat(ToolMetadataMcpMapper.meta(metadata)).containsEntry("when_to_use", "사용 시점") + .containsEntry("when_not_to_use", "사용 제외") + .containsEntry("io_limits", "입출력 제한"); + } +} diff --git a/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSenderTest.java b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSenderTest.java index f91639d0..8d0643e5 100644 --- a/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSenderTest.java +++ b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSenderTest.java @@ -7,6 +7,9 @@ import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; import io.shinhanlife.dap.lib.annotation.GrowToolHint; import io.shinhanlife.dap.lib.config.McpProperties; +import io.shinhanlife.dap.lib.metadata.ToolDefinition; +import io.shinhanlife.dap.lib.metadata.ToolDefinitionRepository; +import io.shinhanlife.dap.lib.metadata.ToolDescription; import io.shinhanlife.dap.lib.util.ToolSchemaResolver; import java.lang.reflect.Field; import java.util.List; @@ -34,6 +37,30 @@ class ToolRegistryHeartbeatSenderTest { assertThat(registeredTools(sender)).isEmpty(); } + @Test + void keepsOnlyFunctionDescriptionAndStoresUsageGuidanceSeparately() throws Exception { + ApplicationContext applicationContext = mock(ApplicationContext.class); + when(applicationContext.getBeansOfType(Object.class)).thenReturn(Map.of("tool", new EnabledTool())); + ToolDefinitionRepository definitions = mock(ToolDefinitionRepository.class); + when(definitions.findByName("test_enabled_tool")).thenReturn(java.util.Optional.of(new ToolDefinition( + "test_enabled_tool", "테스트 도구", "1.0.0", "test", + new ToolDescription("기능 설명", "사용 시점", "사용 제외", "입출력 제한"), + "도구 설명", List.of("질문 1", "질문 2", "질문 3"), true, false, true, + Map.of("type", "object", "properties", Map.of(), "additionalProperties", false), null, + List.of("test"), null, List.of(), "MCP_TOOL"))); + ToolRegistryHeartbeatSender sender = new ToolRegistryHeartbeatSender(applicationContext, new ObjectMapper(), + new McpProperties(), mock(ToolSchemaResolver.class), definitions); + + sender.init(); + + assertThat(sender.getAllScannedTools()).singleElement().satisfies(tool -> { + assertThat(tool.getDescription()).isEqualTo("기능 설명"); + assertThat(tool.getWhenToUse()).isEqualTo("사용 시점"); + assertThat(tool.getWhenNotToUse()).isEqualTo("사용 제외"); + assertThat(tool.getIoLimits()).isEqualTo("입출력 제한"); + }); + } + private void setField(Object target, String name, Object value) throws Exception { Field field = target.getClass().getDeclaredField(name); field.setAccessible(true); @@ -53,4 +80,10 @@ class ToolRegistryHeartbeatSenderTest { void execute() { } } -} \ No newline at end of file + + static class EnabledTool { + @McpTool(name = "test_enabled_tool") + void execute() { + } + } +}