MVC구조로 변경
This commit is contained in:
parent
dc8015a3bf
commit
b2239cde5f
|
|
@ -1,40 +1,108 @@
|
|||
package com.pandol365.dewey.api.controller;
|
||||
|
||||
import com.pandol365.dewey.api.response.McpHealthResponse;
|
||||
import com.pandol365.dewey.api.response.McpInfoResponse;
|
||||
import com.pandol365.dewey.api.dto.request.McpJsonRpcRequest;
|
||||
import com.pandol365.dewey.api.dto.response.McpJsonRpcResponse;
|
||||
import com.pandol365.dewey.api.service.McpService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* MCP (Model Context Protocol) 서버 컨트롤러
|
||||
* MVC 패턴의 Controller 계층
|
||||
* JSON-RPC 2.0 기반 엔드포인트 제공
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/mcp")
|
||||
@RequestMapping("/mcp")
|
||||
@RequiredArgsConstructor
|
||||
public class McpController {
|
||||
|
||||
@GetMapping("/health")
|
||||
public ResponseEntity<McpHealthResponse> health() {
|
||||
return ResponseEntity.ok(
|
||||
McpHealthResponse.builder()
|
||||
.status("UP")
|
||||
.timestamp(LocalDateTime.now())
|
||||
.build()
|
||||
);
|
||||
private final McpService mcpService;
|
||||
|
||||
/**
|
||||
* MCP JSON-RPC 2.0 엔드포인트
|
||||
* 모든 MCP 요청을 처리하는 통합 엔드포인트
|
||||
*/
|
||||
@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()
|
||||
.name("Dewey MCP API")
|
||||
.version("0.0.1-SNAPSHOT")
|
||||
.description("Model Context Protocol API for Dewey")
|
||||
.build()
|
||||
);
|
||||
/**
|
||||
* 요청 메서드에 따라 적절한 서비스 메서드 호출
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object processRequest(McpJsonRpcRequest request) {
|
||||
String method = request.getMethod();
|
||||
McpJsonRpcRequest.McpParams params = request.getParams();
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue