MVC구조로 변경

This commit is contained in:
mskim 2025-12-10 11:09:17 +09:00
parent dc8015a3bf
commit b2239cde5f
1 changed files with 96 additions and 28 deletions

View File

@ -1,40 +1,108 @@
package com.pandol365.dewey.api.controller; package com.pandol365.dewey.api.controller;
import com.pandol365.dewey.api.response.McpHealthResponse; import com.pandol365.dewey.api.dto.request.McpJsonRpcRequest;
import com.pandol365.dewey.api.response.McpInfoResponse; import com.pandol365.dewey.api.dto.response.McpJsonRpcResponse;
import com.pandol365.dewey.api.service.McpService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime; import java.util.Map;
/**
* MCP (Model Context Protocol) 서버 컨트롤러
* MVC 패턴의 Controller 계층
* JSON-RPC 2.0 기반 엔드포인트 제공
*/
@Slf4j
@RestController @RestController
@RequestMapping("/api/mcp") @RequestMapping("/mcp")
@RequiredArgsConstructor @RequiredArgsConstructor
public class McpController { public class McpController {
@GetMapping("/health") private final McpService mcpService;
public ResponseEntity<McpHealthResponse> health() {
return ResponseEntity.ok( /**
McpHealthResponse.builder() * MCP JSON-RPC 2.0 엔드포인트
.status("UP") * 모든 MCP 요청을 처리하는 통합 엔드포인트
.timestamp(LocalDateTime.now()) */
.build() @PostMapping
); public ResponseEntity<McpJsonRpcResponse> handleMcpRequest(@RequestBody McpJsonRpcRequest request) {
log.info("MCP 요청 수신: method={}, id={}", request.getMethod(), request.getId());
try {
Object result = processRequest(request);
McpJsonRpcResponse response = McpJsonRpcResponse.builder()
.jsonrpc("2.0")
.id(request.getId())
.result(result)
.build();
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("MCP 요청 처리 중 오류 발생", e);
McpJsonRpcResponse.McpError error = McpJsonRpcResponse.McpError.builder()
.code(-32603) // Internal error
.message(e.getMessage())
.data(null)
.build();
McpJsonRpcResponse response = McpJsonRpcResponse.builder()
.jsonrpc("2.0")
.id(request.getId())
.error(error)
.build();
return ResponseEntity.ok(response);
}
} }
@GetMapping("/info") /**
public ResponseEntity<McpInfoResponse> info() { * 요청 메서드에 따라 적절한 서비스 메서드 호출
return ResponseEntity.ok( */
McpInfoResponse.builder() @SuppressWarnings("unchecked")
.name("Dewey MCP API") private Object processRequest(McpJsonRpcRequest request) {
.version("0.0.1-SNAPSHOT") String method = request.getMethod();
.description("Model Context Protocol API for Dewey") McpJsonRpcRequest.McpParams params = request.getParams();
.build()
); return switch (method) {
case "initialize" -> mcpService.initialize(params);
case "tools/list" -> mcpService.listTools();
case "tools/call" -> {
Object args = params != null ? params.getArguments() : null;
if (args instanceof Map) {
Map<String, Object> callArgs = (Map<String, Object>) args;
String toolName = callArgs.get("name") != null ? callArgs.get("name").toString() : null;
Object toolArguments = callArgs.get("arguments");
yield mcpService.callTool(toolName, toolArguments);
}
yield mcpService.callTool(null, null);
}
case "resources/list" -> mcpService.listResources();
case "resources/read" -> {
String uri = params != null ? params.getUri() : null;
if (uri == null && params != null && params.getArguments() instanceof Map) {
Map<String, Object> args = (Map<String, Object>) params.getArguments();
uri = args.get("uri") != null ? args.get("uri").toString() : null;
}
yield mcpService.readResource(uri);
}
case "prompts/list" -> mcpService.listPrompts();
case "prompts/get" -> {
Object args = params != null ? params.getArguments() : null;
if (args instanceof Map) {
Map<String, Object> promptArgs = (Map<String, Object>) args;
String promptName = promptArgs.get("name") != null ? promptArgs.get("name").toString() : null;
Object promptArguments = promptArgs.get("arguments");
yield mcpService.getPrompt(promptName, promptArguments);
}
yield mcpService.getPrompt(null, null);
}
default -> throw new IllegalArgumentException("Unknown method: " + method);
};
} }
} }