package com.zy.ai.mcp.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.zy.ai.mcp.config.McpToolsBootstrap; import com.zy.ai.mcp.dto.JsonRpcRequest; import com.zy.ai.mcp.dto.JsonRpcResponse; import com.zy.ai.mcp.dto.ToolDefinition; import com.zy.ai.mcp.dto.ToolRegistry; import com.zy.ai.mcp.service.WcsDataFacade; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import java.util.*; @Slf4j @RestController @RequestMapping("/ai/mcp") public class McpController { private final ToolRegistry registry = new ToolRegistry(); @Autowired private WcsDataFacade wcsDataFacade; public McpController(WcsDataFacade wcsDataFacade) { this.wcsDataFacade = wcsDataFacade; } @PostConstruct public void init() { McpToolsBootstrap.registerAll(registry, wcsDataFacade); log.info("MCP initialized, tools={}", registry.listTools().size()); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Object handle(@RequestBody JsonRpcRequest req, @RequestHeader(value = "Authorization", required = false) String auth) { // (建议)做一个简单鉴权:防止被随便调用生产系统 // if (!"Bearer your-token".equals(auth)) return JsonRpcResponse.err(null, 401, "Unauthorized", null); String id = req.getId(); String method = req.getMethod(); JSONObject params = JSON.parseObject(JSON.toJSONString(req.getParams())); try { if ("initialize".equals(method)) { Map result = new LinkedHashMap(); result.put("serverName", "wcs-mcp"); result.put("serverVersion", "1.0.0"); result.put("capabilities", Arrays.asList("tools")); return JsonRpcResponse.ok(id, result); } if ("tools/list".equals(method)) { Map result = new LinkedHashMap(); result.put("tools", registry.listTools()); // cursor/paging 你后面需要再加 return JsonRpcResponse.ok(id, result); } if ("tools/call".equals(method)) { String toolName = params.getString("name"); JSONObject arguments = params.getJSONObject("arguments"); if (toolName == null || toolName.trim().isEmpty()) { return JsonRpcResponse.err(id, -32602, "Invalid params: missing tool name", null); } ToolDefinition def = registry.get(toolName); if (def == null) { return JsonRpcResponse.err(id, -32601, "Method not found: tool " + toolName, null); } Object output = def.getHandler().handle(arguments == null ? new JSONObject() : arguments); Map result = new LinkedHashMap(); result.put("content", output); // 你也可以按 MCP 常见返回结构做 text/json 分段 return JsonRpcResponse.ok(id, result); } return JsonRpcResponse.err(id, -32601, "Method not found: " + method, null); } catch (Exception e) { log.error("MCP handle error, method={}, params={}", method, params, e); return JsonRpcResponse.err(id, -32000, "Server error", e.getMessage()); } } }