Skip to content

Commit e492942

Browse files
author
黄可欣
committed
移除elicitation能力
1 parent 2cb20b3 commit e492942

6 files changed

Lines changed: 121 additions & 220 deletions

File tree

framework/fel/java/plugins/tool-mcp-client/src/main/java/modelengine/fel/tool/mcp/client/support/DefaultMcpClientFactory.java

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,11 @@
66

77
package modelengine.fel.tool.mcp.client.support;
88

9-
import io.modelcontextprotocol.spec.McpSchema;
109
import modelengine.fel.tool.mcp.client.McpClient;
1110
import modelengine.fel.tool.mcp.client.McpClientFactory;
1211
import modelengine.fitframework.annotation.Component;
1312
import modelengine.fitframework.annotation.Value;
1413

15-
import java.util.function.Consumer;
16-
import java.util.function.Function;
17-
1814
/**
1915
* Represents a factory for creating instances of the {@link DefaultMcpStreamableClient}.
2016
* This class is responsible for initializing and configuring.
@@ -37,32 +33,6 @@ public DefaultMcpClientFactory(@Value("${mcp.client.request.timeout-seconds}") i
3733

3834
@Override
3935
public McpClient create(String baseUri, String sseEndpoint) {
40-
return create(baseUri, sseEndpoint, DefaultMcpClientMessageHandler::defaultLoggingMessageHandler, null);
41-
}
42-
43-
@Override
44-
public McpClient create(String baseUri, String sseEndpoint,
45-
Consumer<McpSchema.LoggingMessageNotification> loggingConsumer) {
46-
return create(baseUri, sseEndpoint, loggingConsumer, null);
47-
}
48-
49-
@Override
50-
public McpClient create(String baseUri, String sseEndpoint,
51-
Function<McpSchema.ElicitRequest, McpSchema.ElicitResult> elicitationHandler) {
52-
return create(baseUri,
53-
sseEndpoint,
54-
DefaultMcpClientMessageHandler::defaultLoggingMessageHandler,
55-
elicitationHandler);
56-
}
57-
58-
@Override
59-
public McpClient create(String baseUri, String sseEndpoint,
60-
Consumer<McpSchema.LoggingMessageNotification> loggingConsumer,
61-
Function<McpSchema.ElicitRequest, McpSchema.ElicitResult> elicitationHandler) {
62-
return new DefaultMcpStreamableClient(baseUri,
63-
sseEndpoint,
64-
requestTimeoutSeconds,
65-
loggingConsumer,
66-
elicitationHandler);
36+
return new DefaultMcpStreamableClient(baseUri, sseEndpoint, requestTimeoutSeconds);
6737
}
6838
}

framework/fel/java/plugins/tool-mcp-client/src/main/java/modelengine/fel/tool/mcp/client/support/DefaultMcpClientMessageHandler.java renamed to framework/fel/java/plugins/tool-mcp-client/src/main/java/modelengine/fel/tool/mcp/client/support/DefaultMcpClientLogHandler.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,37 @@
77
package modelengine.fel.tool.mcp.client.support;
88

99
import io.modelcontextprotocol.spec.McpSchema;
10-
import modelengine.fitframework.annotation.Component;
1110
import modelengine.fitframework.log.Logger;
1211

13-
import java.util.HashMap;
14-
import java.util.Map;
15-
import java.util.Scanner;
16-
1712
/**
1813
* Handles MCP client messages received from MCP server,
1914
* including logging notifications and elicitation requests.
2015
*
2116
* @author 黄可欣
2217
* @since 2025-11-03
2318
*/
24-
@Component
25-
public class DefaultMcpClientMessageHandler {
26-
private static final Logger log = Logger.get(DefaultMcpClientMessageHandler.class);
19+
public class DefaultMcpClientLogHandler {
20+
private static final Logger log = Logger.get(DefaultMcpClientLogHandler.class);
21+
private final String clientId;
22+
23+
/**
24+
* Constructs a new instance of DefaultMcpClientLogHandler.
25+
*
26+
* @param clientId The unique identifier of the MCP client.
27+
*/
28+
public DefaultMcpClientLogHandler(String clientId) {
29+
this.clientId = clientId;
30+
}
2731

2832
/**
2933
* Handles logging messages received from the MCP server.
34+
* Includes the client UUID in the log message for tracking.
3035
*
3136
* @param notification The {@link McpSchema.LoggingMessageNotification} containing the log level and data.
3237
*/
33-
public static void defaultLoggingMessageHandler(McpSchema.LoggingMessageNotification notification) {
34-
log.info("Received logging message from MCP server. [level={}, data={}]",
38+
public void handleLoggingMessage(McpSchema.LoggingMessageNotification notification) {
39+
log.info("Received logging message from MCP server. [clientId={}, level={}, data={}]",
40+
this.clientId,
3541
notification.level(),
3642
notification.data());
3743
}

framework/fel/java/plugins/tool-mcp-client/src/main/java/modelengine/fel/tool/mcp/client/support/DefaultMcpStreamableClient.java

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818
import modelengine.fel.tool.mcp.client.McpClient;
1919
import modelengine.fel.tool.mcp.entity.Tool;
2020
import modelengine.fitframework.log.Logger;
21+
import modelengine.fitframework.util.StringUtils;
22+
import modelengine.fitframework.util.UuidUtils;
2123

2224
import java.io.IOException;
2325
import java.time.Duration;
2426
import java.util.HashMap;
2527
import java.util.List;
2628
import java.util.Map;
27-
import java.util.UUID;
28-
import java.util.function.Consumer;
29-
import java.util.function.Function;
3029
import java.util.stream.Collectors;
3130

3231
/**
@@ -40,6 +39,8 @@ public class DefaultMcpStreamableClient implements McpClient {
4039

4140
private final String clientId;
4241
private final McpSyncClient mcpSyncClient;
42+
private final DefaultMcpClientLogHandler logHandler;
43+
4344
private volatile boolean initialized = false;
4445
private volatile boolean closed = false;
4546

@@ -49,44 +50,30 @@ public class DefaultMcpStreamableClient implements McpClient {
4950
* @param baseUri The base URI of the MCP server.
5051
* @param sseEndpoint The endpoint for the Server-Sent Events (SSE) connection.
5152
* @param requestTimeoutSeconds The timeout duration of requests. Units: seconds.
52-
* @param loggingConsumer The consumer to handle logging messages from the MCP server.
53-
* @param elicitationHandler The function to handle elicitation requests from the MCP server.
5453
*/
55-
public DefaultMcpStreamableClient(String baseUri, String sseEndpoint, int requestTimeoutSeconds,
56-
Consumer<McpSchema.LoggingMessageNotification> loggingConsumer,
57-
Function<McpSchema.ElicitRequest, McpSchema.ElicitResult> elicitationHandler) {
58-
this.clientId = UUID.randomUUID().toString();
54+
public DefaultMcpStreamableClient(String baseUri, String sseEndpoint, int requestTimeoutSeconds) {
55+
this.clientId = UuidUtils.randomUuidString();
5956
notBlank(baseUri, "The MCP server base URI cannot be blank.");
6057
notBlank(sseEndpoint, "The MCP server SSE endpoint cannot be blank.");
61-
log.info("Creating MCP client. [clientId={}, baseUri={}]", clientId, baseUri);
58+
log.info("Creating MCP client. [clientId={}, baseUri={}]", this.clientId, baseUri);
6259
ObjectMapper mapper = new ObjectMapper();
6360
HttpClientStreamableHttpTransport transport = HttpClientStreamableHttpTransport.builder(baseUri)
6461
.jsonMapper(new JacksonMcpJsonMapper(mapper))
6562
.endpoint(sseEndpoint)
6663
.build();
6764

68-
if (elicitationHandler != null) {
69-
this.mcpSyncClient = io.modelcontextprotocol.client.McpClient.sync(transport)
70-
.requestTimeout(Duration.ofSeconds(requestTimeoutSeconds))
71-
.capabilities(McpSchema.ClientCapabilities.builder().elicitation().build())
72-
.loggingConsumer(loggingConsumer)
73-
.elicitation(elicitationHandler)
74-
.jsonSchemaValidator(new DefaultJsonSchemaValidator(mapper))
75-
.build();
76-
} else {
77-
this.mcpSyncClient = io.modelcontextprotocol.client.McpClient.sync(transport)
78-
.requestTimeout(Duration.ofSeconds(requestTimeoutSeconds))
79-
.capabilities(McpSchema.ClientCapabilities.builder().build())
80-
.loggingConsumer(loggingConsumer)
81-
.jsonSchemaValidator(new DefaultJsonSchemaValidator(mapper))
82-
.build();
83-
}
84-
65+
this.logHandler = new DefaultMcpClientLogHandler(this.clientId);
66+
this.mcpSyncClient = io.modelcontextprotocol.client.McpClient.sync(transport)
67+
.requestTimeout(Duration.ofSeconds(requestTimeoutSeconds))
68+
.capabilities(McpSchema.ClientCapabilities.builder().build())
69+
.loggingConsumer(this.logHandler::handleLoggingMessage)
70+
.jsonSchemaValidator(new DefaultJsonSchemaValidator(mapper))
71+
.build();
8572
}
8673

8774
@Override
8875
public String getClientId() {
89-
return clientId;
76+
return this.clientId;
9077
}
9178

9279
/**
@@ -97,9 +84,9 @@ public String getClientId() {
9784
@Override
9885
public void initialize() {
9986
ensureNotClosed();
100-
mcpSyncClient.initialize();
87+
this.mcpSyncClient.initialize();
10188
this.initialized = true;
102-
log.info("MCP client initialized successfully. [clientId={}]", clientId);
89+
log.info("MCP client initialized successfully. [clientId={}]", this.clientId);
10390
}
10491

10592
/**
@@ -115,20 +102,21 @@ public List<Tool> getTools() {
115102
try {
116103
McpSchema.ListToolsResult result = this.mcpSyncClient.listTools();
117104
if (result == null || result.tools() == null) {
118-
log.warn("Failed to get tools list: result is null. [clientId={}]", clientId);
105+
log.warn("Failed to get tools list: result is null. [clientId={}]", this.clientId);
119106
throw new IllegalStateException("Failed to get tools list from MCP server: result is null.");
120107
}
121108

122109
List<Tool> tools = result.tools().stream().map(this::convertToFelTool).collect(Collectors.toList());
123110

124-
log.info("Successfully retrieved tools list. [clientId={}, count={}]", clientId, tools.size());
111+
log.info("Successfully retrieved tools list. [clientId={}, count={}]", this.clientId, tools.size());
125112
tools.forEach(tool -> log.debug("Tool information. [name={}, description={}]",
126113
tool.getName(),
127114
tool.getDescription()));
128115
return tools;
129116
} catch (Exception e) {
130-
log.error("Failed to get tools list. [clientId={}, error={}]", clientId, e.getMessage());
131-
throw new IllegalStateException("Failed to get tools from MCP server. [error=" + e.getMessage() + "]", e);
117+
log.error("Failed to get tools list. [clientId={}, error={}]", this.clientId, e.getMessage());
118+
throw new IllegalStateException(StringUtils.format("Failed to get tools from MCP server. [error={0}]",
119+
e.getMessage()), e);
132120
}
133121
}
134122

@@ -147,19 +135,21 @@ public List<Tool> getTools() {
147135
public Object callTool(String name, Map<String, Object> arguments) {
148136
ensureReady();
149137
try {
150-
log.info("Calling tool. [clientId={}, name={}, arguments={}]", clientId, name, arguments);
138+
log.info("Calling tool. [clientId={}, name={}, arguments={}]", this.clientId, name, arguments);
151139
McpSchema.CallToolResult result =
152140
this.mcpSyncClient.callTool(new McpSchema.CallToolRequest(name, arguments));
153141

154142
if (result == null) {
155-
log.error("Failed to call tool: result is null. [clientId={}, name={}]", clientId, name);
156-
throw new IllegalStateException("Failed to call tool: result is null. [name=" + name + "]");
143+
log.error("Failed to call tool: result is null. [clientId={}, name={}]", this.clientId, name);
144+
throw new IllegalStateException(StringUtils.format("Failed to call tool: result is null. [name={0}]",
145+
name));
157146
}
158147
return processToolResult(result, name);
159148
} catch (Exception e) {
160-
log.error("Failed to call tool. [clientId={}, name={}, error={}]", clientId, name, e.getMessage());
161-
throw new IllegalStateException("Failed to call tool. [name=" + name + ", error=" + e.getMessage() + "]",
162-
e);
149+
log.error("Failed to call tool. [clientId={}, name={}, error={}]", this.clientId, name, e.getMessage());
150+
throw new IllegalStateException(StringUtils.format("Failed to call tool. [name={0}, error={1}]",
151+
name,
152+
e.getMessage()), e);
163153
}
164154
}
165155

@@ -177,26 +167,30 @@ public Object callTool(String name, Map<String, Object> arguments) {
177167
private Object processToolResult(McpSchema.CallToolResult result, String name) {
178168
if (result.isError() != null && result.isError()) {
179169
String errorDetails = extractErrorDetails(result.content());
180-
log.error("Tool returned an error. [clientId={}, name={}, details={}]", clientId, name, errorDetails);
181-
throw new IllegalStateException(
182-
"Tool returned an error. [name=" + name + ", details=" + errorDetails + "]");
170+
log.error("Tool returned an error. [clientId={}, name={}, details={}]", this.clientId, name, errorDetails);
171+
throw new IllegalStateException(StringUtils.format("Tool returned an error. [name={0}, details={1}]",
172+
name,
173+
errorDetails));
183174
}
184175

185176
if (result.content() == null || result.content().isEmpty()) {
186-
log.warn("Tool returned empty content. [clientId={}, name={}]", clientId, name);
177+
log.warn("Tool returned empty content. [clientId={}, name={}]", this.clientId, name);
187178
return null;
188179
}
189180

190181
Object content = result.content().get(0);
191182
if (content instanceof McpSchema.TextContent textContent) {
192-
log.info("Successfully called tool. [clientId={}, name={}, result={}]", clientId, name, textContent.text());
183+
log.info("Successfully called tool. [clientId={}, name={}, result={}]",
184+
this.clientId,
185+
name,
186+
textContent.text());
193187
return textContent.text();
194188
} else if (content instanceof McpSchema.ImageContent imageContent) {
195-
log.info("Successfully called tool: image content. [clientId={}, name={}]", clientId, name);
189+
log.info("Successfully called tool: image content. [clientId={}, name={}]", this.clientId, name);
196190
return imageContent;
197191
} else {
198192
log.info("Successfully called tool. [clientId={}, name={}, contentType={}]",
199-
clientId,
193+
this.clientId,
200194
name,
201195
content.getClass().getSimpleName());
202196
return content;
@@ -213,7 +207,7 @@ public void close() throws IOException {
213207
ensureNotClosed();
214208
this.closed = true;
215209
this.mcpSyncClient.closeGracefully();
216-
log.info("MCP client closed. [clientId={}]", clientId);
210+
log.info("MCP client closed. [clientId={}]", this.clientId);
217211
}
218212

219213
/**
@@ -251,7 +245,8 @@ private Tool convertToFelTool(McpSchema.Tool mcpTool) {
251245
*/
252246
private void ensureNotClosed() {
253247
if (this.closed) {
254-
throw new IllegalStateException("The MCP client is already closed. [clientId=" + clientId + "]");
248+
throw new IllegalStateException(StringUtils.format("The MCP client is already closed. [clientId={0}]",
249+
this.clientId));
255250
}
256251
}
257252

@@ -263,8 +258,8 @@ private void ensureNotClosed() {
263258
private void ensureReady() {
264259
ensureNotClosed();
265260
if (!this.initialized) {
266-
throw new IllegalStateException(
267-
"MCP client is not initialized. [clientId=" + clientId + "]");
261+
throw new IllegalStateException(StringUtils.format("MCP client is not initialized. [clientId={0}]",
262+
this.clientId));
268263
}
269264
}
270265

0 commit comments

Comments
 (0)