fix: remove mcp-annotations and use local annotations
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 0s
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 0s
This commit is contained in:
@@ -49,7 +49,7 @@ dependencies {
|
|||||||
api 'io.modelcontextprotocol.sdk:mcp-json-jackson2'
|
api 'io.modelcontextprotocol.sdk:mcp-json-jackson2'
|
||||||
|
|
||||||
// Boot 3.5 호환 Spring AI 어노테이션 API를 유지합니다.
|
// Boot 3.5 호환 Spring AI 어노테이션 API를 유지합니다.
|
||||||
api 'org.springaicommunity:mcp-annotations:0.9.0'
|
// api 'org.springaicommunity:mcp-annotations:0.9.0'
|
||||||
|
|
||||||
// 이벤트 기반 확장이 필요한 Tool의 공통 Kafka 연동 기능입니다.
|
// 이벤트 기반 확장이 필요한 Tool의 공통 Kafka 연동 기능입니다.
|
||||||
api 'org.springframework.kafka:spring-kafka:3.2.0'
|
api 'org.springframework.kafka:spring-kafka:3.2.0'
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package io.shinhanlife.dat.lib.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(value={ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||||
|
@Retention(value=RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface McpTool {
|
||||||
|
String name() default "";
|
||||||
|
|
||||||
|
String description() default "";
|
||||||
|
|
||||||
|
McpAnnotations annotations() default @McpAnnotations;
|
||||||
|
|
||||||
|
boolean generateOutputSchema() default false;
|
||||||
|
|
||||||
|
String title() default "";
|
||||||
|
|
||||||
|
@Retention(value=RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value={ElementType.ANNOTATION_TYPE})
|
||||||
|
public static @interface McpAnnotations {
|
||||||
|
String title() default "";
|
||||||
|
|
||||||
|
boolean readOnlyHint() default false;
|
||||||
|
|
||||||
|
boolean destructiveHint() default true;
|
||||||
|
|
||||||
|
boolean idempotentHint() default false;
|
||||||
|
|
||||||
|
boolean openWorldHint() default true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package io.shinhanlife.dat.lib.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(value={ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
|
||||||
|
@Retention(value=RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface McpToolParam {
|
||||||
|
boolean required() default true;
|
||||||
|
|
||||||
|
String description() default "";
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
|||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ public class ToolSlaMonitoringAspect {
|
|||||||
private final McpProperties mcpProperties;
|
private final McpProperties mcpProperties;
|
||||||
|
|
||||||
// @McpTool 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
// @McpTool 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
||||||
@Around("@annotation(org.springaicommunity.mcp.annotation.McpTool)")
|
@Around("@annotation(io.shinhanlife.dat.lib.annotation.McpTool)")
|
||||||
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
Method method = signature.getMethod();
|
Method method = signature.getMethod();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class ToolMcpServerConfiguration {
|
|||||||
|
|
||||||
/** Creates the Tool Pod MCP server directly with MCP Java SDK 2.0.0. */
|
/** Creates the Tool Pod MCP server directly with MCP Java SDK 2.0.0. */
|
||||||
@Bean(destroyMethod = "close")
|
@Bean(destroyMethod = "close")
|
||||||
|
@Primary
|
||||||
public McpSyncServer toolMcpServer(HttpServletStreamableServerTransportProvider transportProvider) {
|
public McpSyncServer toolMcpServer(HttpServletStreamableServerTransportProvider transportProvider) {
|
||||||
return McpServer.sync(transportProvider)
|
return McpServer.sync(transportProvider)
|
||||||
.serverInfo("dap-tool-pod", "2.0.0")
|
.serverInfo("dap-tool-pod", "2.0.0")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package io.shinhanlife.dat.lib.mcp;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
||||||
import io.shinhanlife.dat.lib.config.McpProperties;
|
import io.shinhanlife.dat.lib.config.McpProperties;
|
||||||
import io.shinhanlife.dat.mcc.dto.ToolMetadata;
|
import io.shinhanlife.dat.mcc.dto.ToolMetadata;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package io.shinhanlife.dat.lib.util;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
import io.shinhanlife.dat.lib.annotation.McpToolParam;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ public class ToolScaffolder {
|
|||||||
.append(baseName).append("Request req);\n\n");
|
.append(baseName).append("Request req);\n\n");
|
||||||
}
|
}
|
||||||
return "package " + bizPackage + ".usecase;\n\n"
|
return "package " + bizPackage + ".usecase;\n\n"
|
||||||
+ "import org.springaicommunity.mcp.annotation.McpTool;\n"
|
+ "import io.shinhanlife.dat.lib.annotation.McpTool;\n"
|
||||||
+ "import io.shinhanlife.dat.lib.annotation.GrowToolHint;\n"
|
+ "import io.shinhanlife.dat.lib.annotation.GrowToolHint;\n"
|
||||||
+ imports + "\npublic interface " + useCaseBaseName + "UseCase {\n\n" + methods + "}\n";
|
+ imports + "\npublic interface " + useCaseBaseName + "UseCase {\n\n" + methods + "}\n";
|
||||||
}
|
}
|
||||||
@@ -819,7 +819,7 @@ public class ToolScaffolder {
|
|||||||
String serviceInterfaceContent = """
|
String serviceInterfaceContent = """
|
||||||
package %s.usecase;
|
package %s.usecase;
|
||||||
|
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
||||||
import %s.dto.%sRequest;
|
import %s.dto.%sRequest;
|
||||||
import %s.dto.%sResponse;
|
import %s.dto.%sResponse;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class ToolSchemaResolver {
|
|||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> resolve(org.springaicommunity.mcp.annotation.McpTool function,
|
public Map<String, Object> resolve(io.shinhanlife.dat.lib.annotation.McpTool function,
|
||||||
GrowToolHint hint, Class<?> requestType) {
|
GrowToolHint hint, Class<?> requestType) {
|
||||||
if (hint != null && !hint.inputSchemaResource().isBlank()) {
|
if (hint != null && !hint.inputSchemaResource().isBlank()) {
|
||||||
return loadResource(hint.inputSchemaResource());
|
return loadResource(hint.inputSchemaResource());
|
||||||
@@ -29,7 +29,7 @@ public class ToolSchemaResolver {
|
|||||||
* Resolves a response schema only when it is explicitly declared.
|
* Resolves a response schema only when it is explicitly declared.
|
||||||
* A JSON resource has precedence over a DTO marker annotation.
|
* A JSON resource has precedence over a DTO marker annotation.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function,
|
public Map<String, Object> resolveOutput(io.shinhanlife.dat.lib.annotation.McpTool function,
|
||||||
Class<?> responseType, GrowToolHint hint) {
|
Class<?> responseType, GrowToolHint hint) {
|
||||||
if (hint != null && !hint.outputSchemaResource().isBlank()) {
|
if (hint != null && !hint.outputSchemaResource().isBlank()) {
|
||||||
return loadResource(hint.outputSchemaResource());
|
return loadResource(hint.outputSchemaResource());
|
||||||
@@ -40,7 +40,7 @@ public class ToolSchemaResolver {
|
|||||||
/**
|
/**
|
||||||
* Generates a response schema only for DTOs marked with {@link McpOutputSchema}.
|
* Generates a response schema only for DTOs marked with {@link McpOutputSchema}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function,
|
public Map<String, Object> resolveOutput(io.shinhanlife.dat.lib.annotation.McpTool function,
|
||||||
Class<?> responseType) {
|
Class<?> responseType) {
|
||||||
if (responseType == null
|
if (responseType == null
|
||||||
|| responseType == Object.class
|
|| responseType == Object.class
|
||||||
@@ -56,7 +56,7 @@ public class ToolSchemaResolver {
|
|||||||
/**
|
/**
|
||||||
* Retained for callers that use only explicit output schemas.
|
* Retained for callers that use only explicit output schemas.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function) {
|
public Map<String, Object> resolveOutput(io.shinhanlife.dat.lib.annotation.McpTool function) {
|
||||||
return Map.of();
|
return Map.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||||||
|
|
||||||
import io.shinhanlife.dat.lib.config.McpProperties;
|
import io.shinhanlife.dat.lib.config.McpProperties;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import org.springframework.context.support.StaticApplicationContext;
|
import org.springframework.context.support.StaticApplicationContext;
|
||||||
|
|
||||||
class McpToolMethodRegistryTest {
|
class McpToolMethodRegistryTest {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.lang.reflect.Field;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
class ToolRegistryHeartbeatSenderTest {
|
class ToolRegistryHeartbeatSenderTest {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dat.lib.util;
|
package io.shinhanlife.dat.lib.util;
|
||||||
|
|
||||||
|
|
||||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
import io.shinhanlife.dat.lib.annotation.McpToolParam;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
|
|
||||||
class ToolSchemaResolverTest {
|
class ToolSchemaResolverTest {
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ToolSourceUpdaterTest {
|
|||||||
Files.createDirectories(source.getParent());
|
Files.createDirectories(source.getParent());
|
||||||
Files.writeString(source, """
|
Files.writeString(source, """
|
||||||
package example;
|
package example;
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
||||||
interface SampleUseCase {
|
interface SampleUseCase {
|
||||||
@McpTool(name = "cmm_sample_search", description = "old")
|
@McpTool(name = "cmm_sample_search", description = "old")
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class McpToolNameValidatorTest {
|
|||||||
Files.writeString(source, """
|
Files.writeString(source, """
|
||||||
package example;
|
package example;
|
||||||
|
|
||||||
import org.springaicommunity.mcp.annotation.McpTool;
|
import io.shinhanlife.dat.lib.annotation.McpTool;
|
||||||
|
|
||||||
class %s {
|
class %s {
|
||||||
@McpTool(name = "%s")
|
@McpTool(name = "%s")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class McpRequestHeaderFilterTest {
|
|||||||
request.addHeader("employee-no", "ENC(employee)");
|
request.addHeader("employee-no", "ENC(employee)");
|
||||||
request.addHeader("virtual-employee-no", "ENC(virtual)");
|
request.addHeader("virtual-employee-no", "ENC(virtual)");
|
||||||
|
|
||||||
new McpRequestHeaderFilter().doFilter(request, new MockHttpServletResponse(), (req, res) ->
|
new McpRequestHeaderFilter(null).doFilter(request, new MockHttpServletResponse(), (req, res) ->
|
||||||
assertThat(asMap(McpRequestHeaderContext.current())).containsExactly(
|
assertThat(asMap(McpRequestHeaderContext.current())).containsExactly(
|
||||||
Map.entry("requestId", "request-001"),
|
Map.entry("requestId", "request-001"),
|
||||||
Map.entry("guid", "guid-001"),
|
Map.entry("guid", "guid-001"),
|
||||||
|
|||||||
Reference in New Issue
Block a user