Skip to content

Commit 3773db9

Browse files
committed
fit工具链路添加
1 parent 8f0b7e7 commit 3773db9

File tree

21 files changed

+230
-1074
lines changed

21 files changed

+230
-1074
lines changed

framework/fel/java/plugins/tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/support/DefaultMcpStreamableServerTransportProvider.java renamed to framework/fel/java/plugins/tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/DefaultMcpStreamableServerTransportProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Licensed under the MIT License. See License.txt in the project root for license information.
55
*--------------------------------------------------------------------------------------------*/
66

7-
package modelengine.fel.tool.mcp.server.support;
7+
package modelengine.fel.tool.mcp.server;
88

99
import com.fasterxml.jackson.core.type.TypeReference;
1010
import com.fasterxml.jackson.databind.ObjectMapper;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
3+
* This file is a part of the ModelEngine Project.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
7+
package modelengine.fel.tool.mcp.server;
8+
9+
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import io.modelcontextprotocol.server.McpServerFeatures;
11+
import io.modelcontextprotocol.server.McpSyncServerExchange;
12+
import io.modelcontextprotocol.spec.McpSchema;
13+
import modelengine.fel.tool.mcp.entity.ServerSchema;
14+
import modelengine.fel.tool.mcp.entity.Tool;
15+
import modelengine.fel.tool.service.ToolChangedObserver;
16+
import modelengine.fel.tool.service.ToolExecuteService;
17+
import modelengine.fitframework.annotation.Component;
18+
import io.modelcontextprotocol.server.McpSyncServer;
19+
import modelengine.fitframework.log.Logger;
20+
import modelengine.fitframework.util.MapUtils;
21+
import modelengine.fitframework.util.StringUtils;
22+
23+
import java.time.Duration;
24+
import java.util.ArrayList;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.concurrent.ConcurrentHashMap;
28+
import java.util.function.BiFunction;
29+
30+
import static modelengine.fel.tool.info.schema.PluginSchema.TYPE;
31+
import static modelengine.fel.tool.info.schema.ToolsSchema.PROPERTIES;
32+
import static modelengine.fel.tool.info.schema.ToolsSchema.REQUIRED;
33+
import static modelengine.fitframework.inspection.Validation.notNull;
34+
35+
/**
36+
* Mcp Server implemented with MCP SDK.
37+
*
38+
* @author 黄可欣
39+
* @since 2025-09-30
40+
*/
41+
@Component
42+
public class DefaultStreamableSyncMcpServer implements McpServer, ToolChangedObserver {
43+
private static final Logger log = Logger.get(DefaultStreamableSyncMcpServer.class);
44+
private final McpSyncServer mcpSyncServer;
45+
46+
private final Map<String, Tool> tools = new ConcurrentHashMap<>();
47+
private final ToolExecuteService toolExecuteService;
48+
private final List<ToolsChangedObserver> toolsChangedObservers = new ArrayList<>();
49+
50+
/**
51+
* Constructs a new instance of the DefaultMcpServer class.
52+
*
53+
* @param toolExecuteService The service used to execute tools when handling tool call requests.
54+
* @throws IllegalArgumentException If {@code toolExecuteService} is null.
55+
*/
56+
public DefaultStreamableSyncMcpServer(ToolExecuteService toolExecuteService) {
57+
DefaultMcpStreamableServerTransportProvider transportProvider = DefaultMcpStreamableServerTransportProvider.builder()
58+
.objectMapper(new ObjectMapper())
59+
.build();
60+
this.mcpSyncServer = io.modelcontextprotocol.server.McpServer.sync(transportProvider)
61+
.serverInfo("FIT Store MCP Server", "3.6.0-SNAPSHOT")
62+
.capabilities(McpSchema.ServerCapabilities.builder()
63+
.resources(false, true) // Enable resource support
64+
.tools(true) // Enable tool support
65+
.prompts(true) // Enable prompt support
66+
.logging() // Enable logging support
67+
.completions() // Enable completions support
68+
.build())
69+
.requestTimeout(Duration.ofSeconds(10))
70+
.build();
71+
this.toolExecuteService = notNull(toolExecuteService, "The tool execute service cannot be null.");
72+
}
73+
74+
@Override
75+
public ServerSchema getSchema() {
76+
McpSchema.Implementation info = this.mcpSyncServer.getServerInfo();
77+
McpSchema.ServerCapabilities capabilities= this.mcpSyncServer.getServerCapabilities();
78+
return new ServerSchema("2025-06-18", capabilities, info);
79+
}
80+
81+
@Override
82+
public List<Tool> getTools() {
83+
return List.copyOf(this.tools.values());
84+
}
85+
86+
@Override
87+
public void registerToolsChangedObserver(ToolsChangedObserver observer) {
88+
if (observer != null) {
89+
this.toolsChangedObservers.add(observer);
90+
}
91+
}
92+
93+
@Override
94+
public void addTool(String name, String description, McpSchema.JsonSchema inputSchema,
95+
BiFunction<McpSyncServerExchange, McpSchema.CallToolRequest, McpSchema.CallToolResult> callHandler) {
96+
if (StringUtils.isBlank(name)) {
97+
log.warn("Tool addition is ignored: tool name is blank.");
98+
return;
99+
}
100+
if (StringUtils.isBlank(description)) {
101+
log.warn("Tool addition is ignored: tool description is blank. [toolName={}]", name);
102+
return;
103+
}
104+
if (inputSchema == null) {
105+
log.warn("Tool addition is ignored: tool schema is null or empty. [toolName={}]", name);
106+
return;
107+
}
108+
if (callHandler == null) {
109+
log.warn("Tool addition is ignored: tool call handler is null or empty. [toolName={}]", name);
110+
return;
111+
}
112+
113+
McpServerFeatures.SyncToolSpecification toolSpecification = McpServerFeatures.SyncToolSpecification.builder()
114+
.tool(McpSchema.Tool.builder()
115+
.name(name)
116+
.description(description)
117+
.inputSchema(inputSchema)
118+
.build())
119+
.callHandler(callHandler)
120+
.build();
121+
this.mcpSyncServer.addTool(toolSpecification);
122+
123+
Tool tool = new Tool();
124+
tool.setName(name);
125+
tool.setDescription(description);
126+
tool.setInputSchema(inputSchema);
127+
this.tools.put(name, tool);
128+
log.info("Tool added to MCP server. [toolName={}, description={}, schema={}]", name, description, inputSchema);
129+
this.toolsChangedObservers.forEach(ToolsChangedObserver::onToolsChanged);
130+
}
131+
132+
@Override
133+
public void removeTool(String name) {
134+
if (StringUtils.isBlank(name)) {
135+
log.warn("Tool removal is ignored: tool name is blank.");
136+
return;
137+
}
138+
this.mcpSyncServer.removeTool(name);
139+
this.tools.remove(name);
140+
log.info("Tool removed from MCP server. [toolName={}]", name);
141+
this.toolsChangedObservers.forEach(ToolsChangedObserver::onToolsChanged);
142+
}
143+
144+
@Override
145+
public void onToolAdded(String name, String description, Map<String, Object> parameters) {
146+
if (MapUtils.isEmpty(parameters)) {
147+
log.warn("Tool addition is ignored: tool schema is null or empty. [toolName={}]", name);
148+
return;
149+
}
150+
if (!(parameters.get(TYPE) instanceof String)
151+
|| !(parameters.get(PROPERTIES) instanceof Map)
152+
|| !(parameters.get(REQUIRED) instanceof List)) {
153+
154+
log.warn("Invalid parameter schema. [toolName={}]", name);
155+
return;
156+
}
157+
@SuppressWarnings("unchecked")
158+
McpSchema.JsonSchema hkxSchema = new McpSchema.JsonSchema((String) parameters.get(TYPE),
159+
(Map<String, Object>) parameters.get(PROPERTIES), (List<String>) parameters.get(REQUIRED),
160+
null, null,null);
161+
this.addTool(name, description, hkxSchema, (exchange, request) -> {
162+
Map<String, Object> args = request.arguments();
163+
String result = this.toolExecuteService.execute(name, args);
164+
return new McpSchema.CallToolResult(result, true);
165+
});
166+
}
167+
168+
@Override
169+
public void onToolRemoved(String name) {
170+
this.removeTool(name);
171+
}
172+
}

framework/fel/java/plugins/tool-mcp-server/src/main/java/modelengine/fel/tool/mcp/server/McpServer.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
package modelengine.fel.tool.mcp.server;
88

9+
import io.modelcontextprotocol.server.McpSyncServerExchange;
10+
import io.modelcontextprotocol.spec.McpSchema;
911
import modelengine.fel.tool.mcp.entity.ServerSchema;
1012
import modelengine.fel.tool.mcp.entity.Tool;
1113

1214
import java.util.List;
1315
import java.util.Map;
16+
import java.util.function.BiFunction;
1417

1518
/**
1619
* Represents the MCP Server.
@@ -34,13 +37,22 @@ public interface McpServer {
3437
List<Tool> getTools();
3538

3639
/**
37-
* Calls MCP server tool.
40+
* Add a tool.
3841
*
39-
* @param name The tool name as a {@link String}.
40-
* @param arguments The tool arguments as a {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}.
41-
* @return The tool result as a {@link Object}.
42+
* @param name The name of the added tool, as a {@link String}.
43+
* @param description A description of the added tool, as a {@link String}.
44+
* @param inputSchema The parameters associated with the added tool, as a {@link McpSchema.JsonSchema}.
45+
* @param callHandler The tool call handler as a {@link BiFunction}
4246
*/
43-
Object callTool(String name, Map<String, Object> arguments);
47+
void addTool(String name, String description, McpSchema.JsonSchema inputSchema,
48+
BiFunction<McpSyncServerExchange, McpSchema.CallToolRequest, McpSchema.CallToolResult> callHandler);
49+
50+
/**
51+
* Remove a tool.
52+
*
53+
* @param name The name of the removed tool, as a {@link String}.
54+
*/
55+
void removeTool(String name);
4456

4557
/**
4658
* Registers MCP server tools changed observer.

0 commit comments

Comments
 (0)