MVC구조로 변경
This commit is contained in:
parent
dc8015a3bf
commit
b2239cde5f
|
|
@ -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()
|
|
||||||
.status("UP")
|
|
||||||
.timestamp(LocalDateTime.now())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/info")
|
/**
|
||||||
public ResponseEntity<McpInfoResponse> info() {
|
* MCP JSON-RPC 2.0 엔드포인트
|
||||||
return ResponseEntity.ok(
|
* 모든 MCP 요청을 처리하는 통합 엔드포인트
|
||||||
McpInfoResponse.builder()
|
*/
|
||||||
.name("Dewey MCP API")
|
@PostMapping
|
||||||
.version("0.0.1-SNAPSHOT")
|
public ResponseEntity<McpJsonRpcResponse> handleMcpRequest(@RequestBody McpJsonRpcRequest request) {
|
||||||
.description("Model Context Protocol API for Dewey")
|
log.info("MCP 요청 수신: method={}, id={}", request.getMethod(), request.getId());
|
||||||
.build()
|
|
||||||
);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 요청 메서드에 따라 적절한 서비스 메서드 호출
|
||||||
|
*/
|
||||||
|
@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