Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
821b4c8
添加sdk写法相关类
relat-ivity Sep 28, 2025
e4f4006
接入Fit Http逻辑
relat-ivity Sep 29, 2025
1ffc318
使用Choir响应流实现sse发送
relat-ivity Sep 30, 2025
3be1b93
清除废弃文件
relat-ivity Sep 30, 2025
0da5c43
request.headers().all()使用有bug
relat-ivity Sep 30, 2025
b1bf920
接入MCP SDK的streamable服务器
relat-ivity Oct 13, 2025
a97b99a
增加注释
relat-ivity Oct 16, 2025
35b55a4
格式修正
relat-ivity Oct 17, 2025
35f7e68
日志修正
relat-ivity Oct 17, 2025
25125a1
更新MCP SDK版本0.14.0
relat-ivity Oct 17, 2025
8f0b7e7
工具添加
relat-ivity Oct 17, 2025
3773db9
fit工具链路添加
relat-ivity Oct 22, 2025
cc56e29
DefaultMcpServer
relat-ivity Oct 22, 2025
7843661
DefaultMcpServerTest修改
relat-ivity Oct 22, 2025
8ae3896
DefaultMcpServerTest修改
relat-ivity Oct 22, 2025
4a65f2d
input schema判断逻辑修改
relat-ivity Oct 22, 2025
65e0a0f
添加Server Bean
relat-ivity Oct 22, 2025
e6de1a5
修复Get结束Emitter不close的问题
relat-ivity Oct 23, 2025
43eac7d
接口解耦
relat-ivity Oct 23, 2025
deb5e92
test变动
relat-ivity Oct 23, 2025
a954a5e
使用logback-classic提供给SLF4J
relat-ivity Oct 27, 2025
ca3555b
优化连接监控机制
relat-ivity Oct 27, 2025
0af7a76
SLF4J依赖修正
relat-ivity Oct 29, 2025
93cb619
Optimize imports
relat-ivity Oct 29, 2025
7cc67f4
修正类名
relat-ivity Oct 29, 2025
0252343
删除本地Tools保存
relat-ivity Oct 30, 2025
8d85545
ServerSchema旧逻辑删除
relat-ivity Oct 30, 2025
b415e0d
根据0.14.1版本,ObjectMapper更新为McpJsonMapper
relat-ivity Oct 30, 2025
b9296cb
修改onToolAdded()抛出异常
relat-ivity Oct 30, 2025
d8e52be
格式化加onToolAdded()逻辑优化
relat-ivity Nov 4, 2025
d10b0aa
transport类文档
relat-ivity Nov 4, 2025
b019e62
修改md文档
relat-ivity Nov 4, 2025
3fd19f5
更新MD文档
relat-ivity Nov 5, 2025
99517c4
transportProvider优化
relat-ivity Nov 5, 2025
22a4a30
更新README
relat-ivity Nov 5, 2025
5f56153
修改transport类null返回值
relat-ivity Nov 6, 2025
d3760b8
修改transportProvider的handlePOST方法
relat-ivity Nov 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions framework/fel/java/plugins/tool-mcp-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
<groupId>org.fitframework.fel</groupId>
<artifactId>tool-mcp-common</artifactId>
</dependency>
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
<version>0.14.1</version>
</dependency>

<!-- Test -->
<dependency>
Expand Down Expand Up @@ -69,6 +74,16 @@
<configuration>
<category>system</category>
<level>5</level>
<sharedDependencies>
<sharedDependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</sharedDependency>
<sharedDependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</sharedDependency>
</sharedDependencies>
</configuration>
<executions>
<execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

package modelengine.fel.tool.mcp.server.support;

import static modelengine.fitframework.inspection.Validation.notNull;
package modelengine.fel.tool.mcp.server;

import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.spec.McpSchema;
import modelengine.fel.tool.mcp.entity.ServerSchema;
import modelengine.fel.tool.mcp.entity.Tool;
import modelengine.fel.tool.mcp.server.McpServer;
import modelengine.fel.tool.service.ToolChangedObserver;
import modelengine.fel.tool.service.ToolExecuteService;
import modelengine.fitframework.annotation.Component;
Expand All @@ -23,15 +23,22 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static modelengine.fel.tool.info.schema.PluginSchema.TYPE;
import static modelengine.fel.tool.info.schema.ToolsSchema.PROPERTIES;
import static modelengine.fel.tool.info.schema.ToolsSchema.REQUIRED;
import static modelengine.fitframework.inspection.Validation.notNull;

/**
* The default implementation of {@link McpServer}.
* Mcp Server implementing interface {@link McpServer}, {@link ToolChangedObserver}
* with MCP Server Bean {@link McpSyncServer}.
*
* @author 季聿阶
* @since 2025-05-15
*/
@Component
public class DefaultMcpServer implements McpServer, ToolChangedObserver {
private static final Logger log = Logger.get(DefaultMcpServer.class);
public class DefaultMcpStreamableServer implements McpServer, ToolChangedObserver {
private static final Logger log = Logger.get(DefaultMcpStreamableServer.class);
private final McpSyncServer mcpSyncServer;

private final ToolExecuteService toolExecuteService;
private final Map<String, Tool> tools = new ConcurrentHashMap<>();
Expand All @@ -43,8 +50,9 @@ public class DefaultMcpServer implements McpServer, ToolChangedObserver {
* @param toolExecuteService The service used to execute tools when handling tool call requests.
* @throws IllegalArgumentException If {@code toolExecuteService} is null.
*/
public DefaultMcpServer(ToolExecuteService toolExecuteService) {
public DefaultMcpStreamableServer(ToolExecuteService toolExecuteService, McpSyncServer mcpSyncServer) {
this.toolExecuteService = notNull(toolExecuteService, "The tool execute service cannot be null.");
this.mcpSyncServer = mcpSyncServer;
}

@Override
Expand All @@ -53,22 +61,14 @@ public ServerSchema getSchema() {
ServerSchema.Capabilities.Logging logging = new ServerSchema.Capabilities.Logging();
ServerSchema.Capabilities.Tools tools = new ServerSchema.Capabilities.Tools(true);
ServerSchema.Capabilities capabilities = new ServerSchema.Capabilities(logging, tools);
return new ServerSchema("2024-11-05", capabilities, info);
return new ServerSchema("2025-06-18", capabilities, info);
}

@Override
public List<Tool> getTools() {
return List.copyOf(this.tools.values());
}

@Override
public Object callTool(String name, Map<String, Object> arguments) {
log.info("Calling tool. [toolName={}, arguments={}]", name, arguments);
String result = this.toolExecuteService.execute(name, arguments);
log.info("Tool called. [result={}]", result);
return result;
}

@Override
public void registerToolsChangedObserver(ToolsChangedObserver observer) {
if (observer != null) {
Expand All @@ -90,11 +90,45 @@ public void onToolAdded(String name, String description, Map<String, Object> par
log.warn("Tool addition is ignored: tool schema is null or empty. [toolName={}]", name);
return;
}
Object props = parameters.get(PROPERTIES);
Object reqs = parameters.get(REQUIRED);
if (!(parameters.get(TYPE) instanceof String)
|| (props != null && (!(props instanceof Map<?, ?>)
|| ((Map<?, ?>) props).keySet().stream().anyMatch(k -> !(k instanceof String))))
|| (reqs != null && (!(reqs instanceof List<?>)
|| ((List<?>) reqs).stream().anyMatch(v -> !(v instanceof String))))) {
log.warn("Invalid parameter schema. [toolName={}]", name);
return;
}
@SuppressWarnings("unchecked")
McpSchema.JsonSchema inputSchema = new McpSchema.JsonSchema((String) parameters.get(TYPE),
(Map<String, Object>) parameters.get(PROPERTIES), (List<String>) parameters.get(REQUIRED),
null, null,null);
McpServerFeatures.SyncToolSpecification toolSpecification = McpServerFeatures.SyncToolSpecification.builder()
.tool(McpSchema.Tool.builder()
.name(name)
.description(description)
.inputSchema(inputSchema)
.build())
.callHandler((exchange, request) -> {
Map<String, Object> args = request.arguments();
String result = this.toolExecuteService.execute(name, args);
return new McpSchema.CallToolResult(result, false);
})
.build();
Tool tool = new Tool();
tool.setName(name);
tool.setDescription(description);
tool.setInputSchema(parameters);
this.tools.put(name, tool);

try {
this.mcpSyncServer.addTool(toolSpecification);
this.tools.put(name, tool);
} catch (Exception e) {
log.error("Failed to add tool: {}", name, e);
this.tools.remove(name);
return;
}
log.info("Tool added to MCP server. [toolName={}, description={}, schema={}]", name, description, parameters);
this.toolsChangedObservers.forEach(ToolsChangedObserver::onToolsChanged);
}
Expand All @@ -105,6 +139,7 @@ public void onToolRemoved(String name) {
log.warn("Tool removal is ignored: tool name is blank.");
return;
}
this.mcpSyncServer.removeTool(name);
this.tools.remove(name);
log.info("Tool removed from MCP server. [toolName={}]", name);
this.toolsChangedObservers.forEach(ToolsChangedObserver::onToolsChanged);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import modelengine.fel.tool.mcp.entity.Tool;

import java.util.List;
import java.util.Map;

/**
* Represents the MCP Server.
Expand All @@ -33,15 +32,6 @@ public interface McpServer {
*/
List<Tool> getTools();

/**
* Calls MCP server tool.
*
* @param name The tool name as a {@link String}.
* @param arguments The tool arguments as a {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}.
* @return The tool result as a {@link Object}.
*/
Object callTool(String name, Map<String, Object> arguments);

/**
* Registers MCP server tools changed observer.
*
Expand Down

This file was deleted.

This file was deleted.

Loading