diff --git a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java
index 105337870..3695e6af0 100644
--- a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java
+++ b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java
@@ -21,7 +21,7 @@ import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.spec.McpSchema;
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
-import io.shinhanlife.dap.lib.presentation.BusinessToolController;
+import io.shinhanlife.dap.mcc.presentation.BusinessToolController;
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
import java.util.LinkedHashMap;
import java.util.Map;
diff --git a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/BusinessToolController.java b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/BusinessToolController.java
deleted file mode 100644
index 4ca3f6d63..000000000
--- a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/BusinessToolController.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package io.shinhanlife.dap.lib.presentation;
-
-
-/**
- * @package io.shinhanlife.dap.mcc.presentation
- * @className BusinessToolController
- * @description AX HUB 시스템 처리 클래스
- * @author 0986406
- * @create 2026.09.01
- *
- * ---------- 개정이력 ----------
- * 수정일 수정자 수정내용
- * ---------- -------- ---------------------------
- * 2026.09.01 0986406 최초생성
- *
- *
- */
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.networknt.schema.Error;
-import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
-import io.shinhanlife.dap.lib.annotation.McpFunction;
-import io.shinhanlife.dap.lib.annotation.McpTool;
-import io.shinhanlife.dap.lib.config.McpProperties;
-import io.shinhanlife.dap.mcc.dto.ToolMetadata;
-import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
-import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.http.ResponseEntity;
-import org.springframework.util.ClassUtils;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@Slf4j
-@RestController
-@RequestMapping("/")
-@RequiredArgsConstructor
-public class BusinessToolController {
-
- private final ApplicationContext applicationContext;
- private final ObjectMapper objectMapper;
- private final McpProperties mcpProperties;
- private final LocalToolScanner localToolScanner;
- private final ToolArgumentSchemaValidator toolArgumentSchemaValidator;
-
- private final ToolSchemaResolver toolSchemaResolver;
- // 내부 조회용 로컬 Tool 목록 엔드포인트
- @GetMapping("/mcp/api/v1/tools/local")
- public List getLocalTools() {
- return localToolScanner.getAllScannedTools();
- }
-
- // 순수 REST 기반 동적 라우팅 엔드포인트
- @PostMapping("/mcp/{name}")
- public ResponseEntity> executeDynamicTool(
- @PathVariable("name") String functionName,
- @RequestHeader(value = "X-Request-Id", required = false) String headerRequestId,
- @RequestHeader(value = "trace-id", required = false) String traceId,
- @RequestHeader(value = "request-id", required = false) String requestId,
- @RequestHeader(value = "employee-id", required = false) String encryptedEmployeeId,
- @RequestBody(required = false) Map arguments) {
-
- String finalRequestId = headerRequestId;
-
- log.info(" [Tool] IN - trace-id: {}, request-id: {}", traceId, requestId);
- log.info(" [Tool] 동적 툴 실행 요청 수신 (함수명): {}", functionName);
- if (arguments != null) {
- try {
- log.info(" [Tool] 호출 파라미터: {}", objectMapper.writeValueAsString(arguments));
- } catch (Exception e) {
- log.info(" [Tool] 호출 파라미터: {}", arguments);
- }
- }
- Object targetBean = null;
- Method targetMethod = null;
- McpFunction targetFunctionAnnotation = null;
-
- // McpTool 어노테이션 기반 조회가 프록시 문제로 누락될 수 있으므로, 전체 빈을 순회하며 @McpFunction을 찾습니다.
- Map allBeans = applicationContext.getBeansOfType(Object.class);
- outerLoop:
- for (Object bean : allBeans.values()) {
- Class> targetClass = AopUtils.getTargetClass(bean);
- for (Method targetMethodOfClass : targetClass.getDeclaredMethods()) {
- McpFunction mcpFunc = AnnotationUtils.findAnnotation(targetMethodOfClass, McpFunction.class);
- if (mcpFunc != null) {
- String baseName = mcpFunc.name();
- String expectedName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
- ? mcpProperties.getNamespace() + "_" + baseName
- : baseName;
-
- if (expectedName.equals(functionName) || baseName.equals(functionName)) {
- targetBean = bean;
- try {
- targetMethod = bean.getClass().getMethod(targetMethodOfClass.getName(), targetMethodOfClass.getParameterTypes());
- } catch (NoSuchMethodException e) {
- targetMethod = targetMethodOfClass;
- }
- targetFunctionAnnotation = mcpFunc;
- break outerLoop;
- }
- }
- }
- }
-
- if (targetBean == null || targetMethod == null) {
- List availableFunctions = new ArrayList<>();
- for (Object bean : allBeans.values()) {
- Class> targetCls = AopUtils.getTargetClass(bean);
- for (Method m : targetCls.getDeclaredMethods()) {
- McpFunction func = AnnotationUtils.findAnnotation(m, McpFunction.class);
- if (func != null) {
- String baseName = func.name();
- String expName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
- ? mcpProperties.getNamespace() + "_" + baseName : baseName;
- availableFunctions.add(expName + " (in " + targetCls.getSimpleName() + ")");
- }
- }
- }
- log.error("[Tool] 실행할 함수(Method)를 찾을 수 없습니다: {}. 현재 스캔된 툴 메서드 목록: {}", functionName, availableFunctions);
- Map errorDetails = new HashMap<>();
- errorDetails.put("status", "404");
- Map errorBody = new HashMap<>();
- errorBody.put("code", "TOOL_NOT_FOUND");
- errorBody.put("message", "실행할 함수를 찾을 수 없습니다: " + functionName);
- errorBody.put("details", errorDetails);
- if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
-
- return ResponseEntity.status(404).body(errorBody);
- }
- // (기존 차단 로직 제거됨)
-
- // 2. 파라미터 유효성 검증 (JSON Schema)
- if (targetMethod.getParameterCount() > 0) {
- Class> paramType = targetMethod.getParameterTypes()[0];
- if (!Map.class.isAssignableFrom(paramType)) {
- try {
- Map inputSchema = toolSchemaResolver.resolve(targetFunctionAnnotation, paramType);
- List errors = toolArgumentSchemaValidator.validate(inputSchema, arguments);
- if (!errors.isEmpty()) {
- log.error("[Tool] 파라미터 유효성 검증 실패: {}", errors);
- List errorMessages = new ArrayList<>();
- for (Error validationError : errors) {
- errorMessages.add(validationError.getMessage());
- }
- Map errorDetails = new HashMap<>();
- errorDetails.put("status", "422");
- Map errorBody = new HashMap<>();
- errorBody.put("code", "INVALID_PARAM");
- errorBody.put("message", "파라미터 유효성 검증 실패");
- errorBody.put("details", errorDetails);
- if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
-
- return ResponseEntity.status(422).body(errorBody);
- }
- } catch (Exception e) {
- log.error("[Tool] 스키마 검증 중 오류 발생: {}", e.getMessage());
- }
- }
- }
-
- log.info("[Tool] 리플렉션 직접 실행 -> Method: {}", targetMethod.getName());
-
- try {
- // 3. DTO 파라미터 자동 매핑 (Map -> DTO)
- Object invokeArgument = arguments;
- if (targetMethod.getParameterCount() > 0 && arguments != null) {
- Class> paramType = targetMethod.getParameterTypes()[0];
- if (!Map.class.isAssignableFrom(paramType)) {
- invokeArgument = objectMapper.convertValue(arguments, paramType);
- log.info("[Tool] DTO 자동 매핑 성공: {}", paramType.getSimpleName());
- }
- }
-
- long startTime = System.currentTimeMillis();
- Object methodResult = null;
- if (targetMethod.getParameterCount() == 0) {
- methodResult = targetMethod.invoke(targetBean);
- } else {
- methodResult = targetMethod.invoke(targetBean, invokeArgument);
- }
-
- Map outputSchema = toolSchemaResolver.resolveOutput(targetFunctionAnnotation, targetMethod.getReturnType());
- if (!outputSchema.isEmpty()) {
- List outputErrors = toolArgumentSchemaValidator.validateValue(outputSchema, methodResult);
- if (!outputErrors.isEmpty()) {
- log.error("[Tool] Output schema validation failed. tool={}, errors={}",
- functionName, outputErrors);
- Map errorBody = new HashMap<>();
- errorBody.put("code", "INVALID_TOOL_RESPONSE");
- errorBody.put("message", "Tool response does not match its output schema");
- if (finalRequestId != null) {
- errorBody.put("request_id", finalRequestId);
- }
- return ResponseEntity.internalServerError().body(errorBody);
- }
- }
-
- long elapsed = System.currentTimeMillis() - startTime;
-
- // 5. 결과 반환 (순수 REST 응답)
- try {
- log.info("[Tool Execution] Output Schema Result: {}", objectMapper.writeValueAsString(methodResult));
- } catch (Exception e) {
- log.info("[Tool Execution] Output Schema Result: {}", methodResult);
- }
-
- log.info(" [Tool] OUT - trace-id: {}, request-id: {}", traceId, requestId);
-
- ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok();
- if (traceId != null) responseBuilder.header("trace-id", traceId);
- if (requestId != null) responseBuilder.header("request-id", requestId);
-
- return responseBuilder.body(methodResult);
-
- } catch (Exception e) {
- log.error("[Tool] 리플렉션 실행 중 예외 발생: {}", e.getMessage());
- Map errorDetails = new HashMap<>();
- errorDetails.put("status", "500");
- Map errorBody = new HashMap<>();
- errorBody.put("code", "TOOL_ERROR");
- errorBody.put("message", "Tool execution failed");
- errorDetails.clear(); // Hide details for upstream errors
- errorBody.put("details", errorDetails);
- if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
-
- return ResponseEntity.status(502).body(errorBody);
- }
- }
-}
diff --git a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/ToolManifestController.java b/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/ToolManifestController.java
deleted file mode 100644
index 057a68acb..000000000
--- a/dap-was-lib/src/main/java/io/shinhanlife/dap/lib/presentation/ToolManifestController.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package io.shinhanlife.dap.lib.presentation;
-
-/**
- * @package io.shinhanlife.dap.lib.presentation
- * @className ToolManifestController
- * @description AX HUB 시스템 처리 클래스
- * @author 0986406
- * @create 2026.09.01
- *
- * ---------- 개정이력 ----------
- * 수정일 수정자 수정내용
- * ---------- -------- ---------------------------
- * 2026.09.01 0986406 최초생성
- *
- *
- */
-
-
-import io.shinhanlife.dap.lib.manifest.ToolManifestResponse;
-import io.shinhanlife.dap.lib.manifest.ToolManifestService;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RestController;
-
-/** Read-only Tool Service manifest endpoint for MCP background discovery. */
-@RestController
-public class ToolManifestController {
-
- private final ToolManifestService toolManifestService;
-
- public ToolManifestController(ToolManifestService toolManifestService) {
- this.toolManifestService = toolManifestService;
- }
-
- @GetMapping(value = "/tool-manifest", produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity getManifest(
- @RequestHeader(value = HttpHeaders.IF_NONE_MATCH, required = false) String ifNoneMatch) {
- ToolManifestResponse manifest = toolManifestService.currentManifest();
- String eTag = '"' + manifest.revision() + '"';
- if (eTag.equals(ifNoneMatch)) {
- return ResponseEntity.status(304).eTag(eTag).build();
- }
- return ResponseEntity.ok().eTag(eTag).body(manifest);
- }
-}
\ No newline at end of file
diff --git a/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilterTest.java b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilterTest.java
index dffd2d178..7479ea3b8 100644
--- a/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilterTest.java
+++ b/dap-was-lib/src/test/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilterTest.java
@@ -26,7 +26,7 @@ import static org.mockito.Mockito.when;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpSyncServer;
-import io.shinhanlife.dap.lib.presentation.BusinessToolController;
+import io.shinhanlife.dap.mcc.presentation.BusinessToolController;
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
import java.lang.reflect.Method;
import java.util.Map;
diff --git a/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/BusinessToolControllerHeaderContractTest.java b/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/BusinessToolControllerHeaderContractTest.java
index 243283d36..f1f5b21d0 100644
--- a/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/BusinessToolControllerHeaderContractTest.java
+++ b/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/BusinessToolControllerHeaderContractTest.java
@@ -1,7 +1,7 @@
-package io.shinhanlife.dap.lib.presentation;
+package io.shinhanlife.dap.mcc.presentation;
/**
- * @package io.shinhanlife.dap.lib.presentation
+ * @package io.shinhanlife.dap.mcc.presentation
* @className BusinessToolControllerHeaderContractTest
* @description AX HUB 시스템 처리 클래스
* @author 0986406
diff --git a/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/ToolTestConsoleResourceTest.java b/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/ToolTestConsoleResourceTest.java
index d43fb9747..bb08a254c 100644
--- a/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/ToolTestConsoleResourceTest.java
+++ b/dap-was-lib/src/test/java/io/shinhanlife/dap/mcc/presentation/ToolTestConsoleResourceTest.java
@@ -1,7 +1,7 @@
-package io.shinhanlife.dap.lib.presentation;
+package io.shinhanlife.dap.mcc.presentation;
/**
- * @package io.shinhanlife.dap.lib.presentation
+ * @package io.shinhanlife.dap.mcc.presentation
* @className ToolTestConsoleResourceTest
* @description AX HUB 시스템 처리 클래스
* @author 0986406