commit
2dc4155d77
@ -0,0 +1,16 @@
|
|||||||
|
Thumbs.db
|
||||||
|
.DS_Store
|
||||||
|
target/
|
||||||
|
out/
|
||||||
|
.micronaut/
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.m2/
|
||||||
|
maven-wrapper.jar
|
||||||
|
maven-wrapper.properties
|
@ -0,0 +1,35 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
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.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSE控制器类
|
||||||
|
* 用于处理SSE连接请求和事件发送
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mcp/sse")
|
||||||
|
public class SseController {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(SseController.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SseBroadcaster broadcaster;
|
||||||
|
|
||||||
|
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
|
public SseEmitter connectSse() {
|
||||||
|
log.info("Client requesting SSE connection...");
|
||||||
|
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
|
||||||
|
broadcaster.registerEmitter(emitter);
|
||||||
|
broadcaster.sendEndpointEvent(emitter);
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用工具的结果类
|
||||||
|
* 用于封装工具调用后的返回数据和错误状态
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class CallToolResult extends Data {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具调用返回的内容数据列表
|
||||||
|
*/
|
||||||
|
private List<TextContentData> content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具调用是否出错
|
||||||
|
*/
|
||||||
|
private Boolean isError;
|
||||||
|
|
||||||
|
public CallToolResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallToolResult(List<TextContentData> content, Boolean isError) {
|
||||||
|
this.content = content;
|
||||||
|
this.isError = isError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallToolResult(List<TextContentData> content) {
|
||||||
|
this(content, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TextContentData> getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(List<TextContentData> content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getIsError() {
|
||||||
|
return isError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsError(Boolean isError) {
|
||||||
|
this.isError = isError;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可序列化基类.
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public class Data implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化结果类
|
||||||
|
* 用于封装服务器初始化后的能力信息
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class InitializeResult extends Data {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器能力信息
|
||||||
|
*/
|
||||||
|
private ServerCapabilities capabilities;
|
||||||
|
|
||||||
|
public InitializeResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitializeResult(ServerCapabilities capabilities) {
|
||||||
|
this.capabilities = capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerCapabilities getCapabilities() {
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCapabilities(ServerCapabilities capabilities) {
|
||||||
|
this.capabilities = capabilities;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入模式类
|
||||||
|
* 用于定义工具输入参数的结构和验证规则
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class InputSchema extends Data {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入模式的类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入模式的属性定义
|
||||||
|
*/
|
||||||
|
private Map<String, Object> properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入模式的必填字段列表
|
||||||
|
*/
|
||||||
|
private List<String> required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入模式是否允许额外属性
|
||||||
|
*/
|
||||||
|
private Boolean additionalProperties;
|
||||||
|
|
||||||
|
public InputSchema() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputSchema(String type, Map<String, Object> properties, List<String> required, Boolean additionalProperties) {
|
||||||
|
this.type = type;
|
||||||
|
this.properties = properties;
|
||||||
|
this.required = required;
|
||||||
|
this.additionalProperties = additionalProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(Map<String, Object> properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRequired() {
|
||||||
|
return required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequired(List<String> required) {
|
||||||
|
this.required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAdditionalProperties() {
|
||||||
|
return additionalProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdditionalProperties(Boolean additionalProperties) {
|
||||||
|
this.additionalProperties = additionalProperties;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具列表结果类
|
||||||
|
* 用于封装可用工具的列表信息
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class ListToolsResult extends Data {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具列表
|
||||||
|
*/
|
||||||
|
private List<ToolSpecificationData> tools;
|
||||||
|
|
||||||
|
public ListToolsResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListToolsResult(List<ToolSpecificationData> tools) {
|
||||||
|
this.tools = tools;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ToolSpecificationData> getTools() {
|
||||||
|
return tools;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTools(List<ToolSpecificationData> tools) {
|
||||||
|
this.tools = tools;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误信息类
|
||||||
|
* 用于封装错误代码和错误消息
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class McpError extends Data {
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public McpError() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpError(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCP协议请求类
|
||||||
|
* 用于封装JSON-RPC格式的请求数据
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class McpRequest extends Data {
|
||||||
|
private String jsonrpc;
|
||||||
|
private Long id;
|
||||||
|
private String method;
|
||||||
|
private JsonNode params; // Use JsonNode for flexible params
|
||||||
|
|
||||||
|
public McpRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpRequest(String jsonrpc, Long id, String method, JsonNode params) {
|
||||||
|
this.jsonrpc = jsonrpc;
|
||||||
|
this.id = id;
|
||||||
|
this.method = method;
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJsonrpc() {
|
||||||
|
return jsonrpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJsonrpc(String jsonrpc) {
|
||||||
|
this.jsonrpc = jsonrpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(String method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonNode getParams() {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParams(JsonNode params) {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCP协议响应类
|
||||||
|
* 用于封装JSON-RPC格式的响应数据
|
||||||
|
* 支持成功结果和错误信息的返回
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class McpResponse extends Data {
|
||||||
|
private String jsonrpc;
|
||||||
|
private Long id;
|
||||||
|
private Object result; // Can be ListToolsResult, CallToolResult, etc.
|
||||||
|
private McpError error; // Optional error field
|
||||||
|
|
||||||
|
public McpResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpResponse(String jsonrpc, Long id, Object result, McpError error) {
|
||||||
|
this.jsonrpc = jsonrpc;
|
||||||
|
this.id = id;
|
||||||
|
this.result = result;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpResponse(Long id, Object result) {
|
||||||
|
this("2.0", id, result, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpResponse(Long id, McpError error) {
|
||||||
|
this("2.0", id, null, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJsonrpc() {
|
||||||
|
return jsonrpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJsonrpc(String jsonrpc) {
|
||||||
|
this.jsonrpc = jsonrpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(Object result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public McpError getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(McpError error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器能力类
|
||||||
|
* 用于封装服务器支持的功能和特性
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class ServerCapabilities extends Data {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文本内容数据类
|
||||||
|
* 用于封装文本类型的内容数据
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class TextContentData extends Data {
|
||||||
|
@JsonProperty("type")
|
||||||
|
private String type;
|
||||||
|
@JsonProperty("text")
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public TextContentData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextContentData(String type, String text) {
|
||||||
|
this.type = type;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextContentData(String text) {
|
||||||
|
this("text", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package xyz.wbsite.mcp.basic.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具规格数据类
|
||||||
|
* 用于封装工具的基本信息和输入规范
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
*/
|
||||||
|
public class ToolSpecificationData extends Data {
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private InputSchema inputSchema;
|
||||||
|
|
||||||
|
public ToolSpecificationData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToolSpecificationData(String name, String description, InputSchema inputSchema) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.inputSchema = inputSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputSchema getInputSchema() {
|
||||||
|
return inputSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputSchema(InputSchema inputSchema) {
|
||||||
|
this.inputSchema = inputSchema;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
server.port=8080
|
Loading…
Reference in new issue