Junjie
17 小时以前 411ff551ae7641dfc5c9331e99bf8b6e5770e2fa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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<String, Object> result = new LinkedHashMap<String, Object>();
                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<String, Object> result = new LinkedHashMap<String, Object>();
                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<String, Object> result = new LinkedHashMap<String, Object>();
                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());
        }
    }
}