diff --git a/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/controller/McpRouterController.java b/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/controller/McpRouterController.java index f6e74b4..d399eb0 100644 --- a/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/controller/McpRouterController.java +++ b/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/controller/McpRouterController.java @@ -113,8 +113,21 @@ public class McpRouterController { // 1. [신규] 표준 MCP 파이프라인 호출 (가장 중요!) @Operation(summary = "MCP 파이프라인 호출", description = "MCP 표준 파이프라인(ExecuteService)을 통해 레거시 툴을 호출합니다.") @PostMapping("/tools/call") - public ResponseEntity callTool(@RequestBody Map payload, @RequestAttribute(value = "tenantId", required = false) String tenantId) { - log.info("[MCP 표준] ExecuteService 파이프라인을 통한 툴 호출 시작 (Tenant: {})", tenantId); + public ResponseEntity callTool( + @RequestHeader(value = "X-Trace-Id", required = false) String traceId, + @RequestHeader(value = "X-Agent-Id", required = false) String agentId, + @RequestHeader(value = "X-User-Prompt", required = false) String userPrompt, + @RequestBody Map payload, + @RequestAttribute(value = "tenantId", required = false) String tenantId) { + + // 메타데이터 주입 + java.util.Map meta = new java.util.HashMap<>(); + meta.put("traceId", traceId != null ? traceId : java.util.UUID.randomUUID().toString()); + meta.put("agentId", agentId != null ? agentId : "UNKNOWN"); + meta.put("userPrompt", userPrompt != null ? userPrompt : ""); + payload.put("meta", meta); + + log.info("[MCP 표준] ExecuteService 파이프라인을 통한 툴 호출 시작 (Tenant: {}, Trace: {})", tenantId, meta.get("traceId")); if (payload != null) { try { log.info(" [Gateway] AI Agent 요청 파라미터: {}", objectMapper.writeValueAsString(payload)); diff --git a/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/router/RequestValidator.java b/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/router/RequestValidator.java index df579e0..0af8f62 100644 --- a/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/router/RequestValidator.java +++ b/src/main/java/io/shinhanlife/axhub/biz/mcp/gateway/router/RequestValidator.java @@ -40,23 +40,28 @@ public class RequestValidator { throw new IllegalArgumentException("params.arguments 객체가 누락되었습니다."); } - // 2. 필수 파라미터 누락 및 빈 값 검증 (arguments 내에서 검증) + // 2. 필수 파라미터 누락 및 빈 값 검증 (meta 내에서 검증) + Map meta = (Map) payload.get("meta"); + if (meta == null) { + throw new IllegalArgumentException("메타데이터 객체(meta)가 누락되었습니다."); + } + for (String field : REQUIRED_FIELDS) { - if (!arguments.containsKey(field)) { - log.error(" [Validator] 검증 실패: 필수 키 누락 [{}]", field); + if (!meta.containsKey(field)) { + log.error(" [Validator] 검증 실패: 필수 메타데이터 누락 [{}]", field); throw new IllegalArgumentException("필수 파라미터가 누락되었습니다: " + field); } - Object value = arguments.get(field); + Object value = meta.get(field); if (value == null || value.toString().trim().isEmpty()) { - log.error(" [Validator] 검증 실패: 필수 키의 값이 비어 있음 [{}]", field); + log.error(" [Validator] 검증 실패: 필수 메타데이터의 값이 비어 있음 [{}]", field); throw new IllegalArgumentException("필수 파라미터의 값이 비어있을 수 없습니다: " + field); } } // 3. 비즈니스 로직에 따른 추가 데이터 길이 또는 타입 검증 (예: 프롬프트 길이) - String traceId = arguments.get("traceId").toString(); - String userPrompt = arguments.get("userPrompt").toString(); + String traceId = meta.get("traceId").toString(); + String userPrompt = meta.get("userPrompt").toString(); if (userPrompt.length() > 2000) { log.warn(" [Validator] 프롬프트 길이 초과 (Trace ID: {})", traceId);