[FEL] MCP streamable HTTP server implemented with MCP SDK #344
[FEL] MCP streamable HTTP server implemented with MCP SDK #344CodeCasterX merged 37 commits intoModelEngine-Group:mainfrom
Conversation
PR #344 代码检视报告这是一个将 MCP 服务器从自定义实现迁移到官方 MCP Java SDK 的重构 PR。总体来说这是一个积极的改进,但有一些需要注意的地方。 主要变更概述添加了 921 行,删除了 895 行,涉及 19 个文件
✅ 优点
|
...ool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/DefaultMcpStreamableServer.java
Outdated
Show resolved
Hide resolved
...ool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/DefaultMcpStreamableServer.java
Outdated
Show resolved
Hide resolved
...tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/bean/DefaultMcpServerBean.java
Outdated
Show resolved
Hide resolved
...tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/bean/DefaultMcpServerBean.java
Outdated
Show resolved
Hide resolved
...ool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/DefaultMcpStreamableServer.java
Outdated
Show resolved
Hide resolved
...er/src/test/java/modelengine/fel/tool/mcp/server/support/DefaultMcpStreamableServerTest.java
Outdated
Show resolved
Hide resolved
.../java/modelengine/fel/tool/mcp/server/transport/FitMcpStreamableServerTransportProvider.java
Outdated
Show resolved
Hide resolved
.../java/modelengine/fel/tool/mcp/server/transport/FitMcpStreamableServerTransportProvider.java
Outdated
Show resolved
Hide resolved
...ool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/DefaultMcpStreamableServer.java
Outdated
Show resolved
Hide resolved
.../java/modelengine/fel/tool/mcp/server/transport/FitMcpStreamableServerTransportProvider.java
Show resolved
Hide resolved
代码更改超时时间可配置public McpSyncServer mcpSyncServer(FitMcpStreamableServerTransportProvider transportProvider,
@Value("${mcp.server.request.timeout-seconds}") int requestTimeoutSeconds) parameters校验太过于复杂,抽取函数 private boolean isValidParameterSchema(Map<String, Object> parameters) {
Object type = parameters.get(TYPE);
if (!(type instanceof String)) {
return false;
}
Object props = parameters.get(PROPERTIES);
if (!(props instanceof Map<?, ?> propsMap)) {
return false;
}
if (propsMap.keySet().stream().anyMatch(k -> !(k instanceof String))) {
return false;
}
Object reqs = parameters.get(REQUIRED);
if (!(reqs instanceof List<?> reqsList)) {
return false;
}
if (reqsList.stream().anyMatch(v -> !(v instanceof String))) {
return false;
}
return true;
}工具执行增加异常处理.callHandler((exchange, request) -> {
try {
Map<String, Object> args = request.arguments();
String result = this.toolExecuteService.execute(name, args);
return new McpSchema.CallToolResult(result, false);
} catch (IllegalArgumentException e) {
log.warn("Invalid arguments for tool execution. [toolName={}, error={}]", name, e.getMessage());
return new McpSchema.CallToolResult("Error: Invalid arguments - " + e.getMessage(), true);
} catch (Exception e) {
log.error("Failed to execute tool. [toolName={}]", name, e);
return new McpSchema.CallToolResult("Error: Tool execution failed - " + e.getMessage(), true);
}
})删除本地Tools保存,避免线程问题删除tools的存储, public List<Tool> getTools() {
return this.mcpSyncServer.listTools().stream()
.map(this::convertToFelTool)
.collect(Collectors.toList());
}删除Server里的ServerSchema相关旧方法删除 Test改为非mock的McpServer由于另存的 @BeforeEach
void setup() {
this.toolExecuteService = mock(ToolExecuteService.class);
McpServerConfig config = new McpServerConfig();
this.mcpSyncServer = config.mcpSyncServer(config.fitMcpStreamableServerTransportProvider(), 10);
}McpJsonMapper根据0.14.1版本的MCP SDK, 以及其他代码规范改动 |
...a/plugins/tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/McpServerConfig.java
Outdated
Show resolved
Hide resolved
...server/src/main/java/modelengine/fel/tool/mcp/server/support/DefaultMcpStreamableServer.java
Show resolved
Hide resolved
framework/fel/java/plugins/tool-mcp-server/服务器transport相关类维护文档.md
Outdated
Show resolved
Hide resolved
framework/fel/java/plugins/tool-mcp-server/服务器transport相关类维护文档.md
Outdated
Show resolved
Hide resolved
framework/fel/java/plugins/tool-mcp-server/服务器transport相关类维护文档.md
Outdated
Show resolved
Hide resolved
.../java/modelengine/fel/tool/mcp/server/transport/FitMcpStreamableServerTransportProvider.java
Show resolved
Hide resolved
变动记录从原本的
测试结果与原本测试结果相同,本次改动不影响功能实现。 |


🔗 相关问题 / Related Issue
Issue 链接 / Issue Link: #342 👈👈
📋 变更类型 / Type of Change
📝 变更目的 / Purpose of the Change
根据MCP协议2025-06-18版本新的规范,MCP传输调整为streamable HTTP。并且新增服务器Elicitation与服务器Log通知等新功能。
在原有的FEL中实现的SSE MCP服务器中接入这些新功能需要较大工作量,所以需要接入MCP SDK实现。
📋 主要变更 / Brief Changelog
tool-mcp-server插件中添加0.14.1版本的MCP Java SDK的依赖DefaultMcpStreamableServerTransportProvider类使用FIT的HTTP实现完成Streamable MCP服务器的HTTP传输逻辑DefaulMcpServerBean中构建DefaultMcpStreamableServerTransportProvider和McpSyncServer的BeanDefaultMcpServer类中完成FIT的MCP服务器接口的实现🧪 验证变更 / Verifying this Change
测试步骤 / Test Steps
npx @modelcontextprotocol/inspector测试服务器功能测试覆盖 / Test Coverage
📸 截图 / Screenshots
截图包括MCP Inspector、Postman和服务器logger结果
1. initialize
客户端POST发送


initialize,服务端HTTP response回复initialize信息,客户端POST发送notifications/initialized2. logging/setLevel
客户端POST发送


logging/setLevel,服务端建立SSE发送result,然后关闭SSE连接3. GET建立SSE
客户端GET请求建立SSE长连接,客户端通过SSE接收


notifications/tools/list_changed通知。关闭GET连接后SSE长连接关闭。4. tools/list
添加addTool工具,客户端POST发送


tools/list,服务端建立SSE发送result,然后关闭SSE连接5. tools/call
调用addTool工具,调中包括Elicitation和服务器Log通知。
tools/call请求调用addTool工具elicitation/create请求Elicitationnotifications/message通知服务器Log✅ 贡献者检查清单 / Contributor Checklist
请确保你的 Pull Request 符合以下要求 / Please ensure your Pull Request meets the following requirements:
基本要求 / Basic Requirements:
代码质量 / Code Quality:
测试要求 / Testing Requirements:
mvn -B clean package -Dmaven.test.skip=true,elsa README 中的编译检查 / Basic checks passmvn clean install/ Unit tests pass文档和兼容性 / Documentation and Compatibility:
📋 附加信息 / Additional Notes
由于引入MCP Java SDK中使用SLF4J作为日志,启动时会warning:
SLF4J(W): No SLF4J providers were found. SLF4J(W): Defaulting to no-operation (NOP) logger implementation SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.解决方法:在
build/shared文件夹下,添加日志provider的依赖,例如slf4j-api和slf4j-simple的jar文件审查者注意事项 / Reviewer Notes: