Skip to content

Commit aaf7add

Browse files
committed
Store optional json schemas in cache
1 parent 31f453e commit aaf7add

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

mcp/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.HashMap;
99
import java.util.List;
1010
import java.util.Map;
11+
import java.util.Optional;
1112
import java.util.concurrent.ConcurrentHashMap;
1213
import java.util.concurrent.TimeoutException;
1314
import java.util.concurrent.atomic.AtomicBoolean;
@@ -26,6 +27,7 @@
2627
import io.modelcontextprotocol.spec.McpSchema.CreateMessageResult;
2728
import io.modelcontextprotocol.spec.McpSchema.GetPromptRequest;
2829
import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
30+
import io.modelcontextprotocol.spec.McpSchema.JsonSchema;
2931
import io.modelcontextprotocol.spec.McpSchema.ListPromptsResult;
3032
import io.modelcontextprotocol.spec.McpSchema.LoggingLevel;
3133
import io.modelcontextprotocol.spec.McpSchema.LoggingMessageNotification;
@@ -130,7 +132,7 @@ public class McpAsyncClient {
130132
/**
131133
* Cached tool output schemas.
132134
*/
133-
private final ConcurrentHashMap<String, McpSchema.JsonSchema> toolsOutputSchemaCache;
135+
private final ConcurrentHashMap<String, Optional<JsonSchema>> toolsOutputSchemaCache;
134136

135137
/**
136138
* Roots define the boundaries of where servers can operate within the filesystem,
@@ -301,7 +303,7 @@ public McpSchema.Implementation getClientInfo() {
301303
* Get the cached tool output schemas.
302304
* @return The cached tool output schemas
303305
*/
304-
public HashMap<String, McpSchema.JsonSchema> getToolsOutputSchemaCache() {
306+
public ConcurrentHashMap<String, Optional<JsonSchema>> getToolsOutputSchemaCache() {
305307
return this.toolsOutputSchemaCache;
306308
}
307309

@@ -579,7 +581,8 @@ public Mono<McpSchema.ListToolsResult> listTools(String cursor) {
579581
if (result.tools() != null) {
580582
// Cache tools output schema
581583
result.tools()
582-
.forEach(tool -> this.toolsOutputSchemaCache.put(tool.name(), tool.outputSchema()));
584+
.forEach(tool -> this.toolsOutputSchemaCache.put(tool.name(),
585+
Optional.ofNullable(tool.outputSchema())));
583586
}
584587
});
585588
});

mcp/src/main/java/io/modelcontextprotocol/client/McpSyncClient.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
package io.modelcontextprotocol.client;
66

77
import java.time.Duration;
8-
import java.util.HashMap;
8+
import java.util.Optional;
99
import java.util.Set;
10+
import java.util.concurrent.ConcurrentHashMap;
1011

1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
@@ -244,18 +245,19 @@ public Object ping() {
244245
*/
245246
public McpSchema.CallToolResult callTool(McpSchema.CallToolRequest callToolRequest) {
246247
McpSchema.CallToolResult result = this.delegate.callTool(callToolRequest).block();
247-
HashMap<String, McpSchema.JsonSchema> toolsOutputSchemaCache = this.delegate.getToolsOutputSchemaCache();
248+
ConcurrentHashMap<String, Optional<McpSchema.JsonSchema>> toolsOutputSchemaCache = this.delegate
249+
.getToolsOutputSchemaCache();
248250
// Should not be triggered but added for completeness
249251
if (!toolsOutputSchemaCache.containsKey(callToolRequest.name())) {
250252
throw new McpError("Tool with name '" + callToolRequest.name() + "' not found");
251253
}
252-
if (result != null && toolsOutputSchemaCache.get(callToolRequest.name()) != null) {
254+
Optional<McpSchema.JsonSchema> optOutputSchema = toolsOutputSchemaCache.get(callToolRequest.name());
255+
if (result != null && optOutputSchema != null && optOutputSchema.isPresent()) {
253256
if (result.structuredContent() == null) {
254257
throw new McpError("CallToolResult validation failed: structuredContent is null and "
255258
+ "does not match tool outputSchema.");
256259
}
257-
258-
McpSchema.JsonSchema outputSchema = toolsOutputSchemaCache.get(callToolRequest.name());
260+
McpSchema.JsonSchema outputSchema = optOutputSchema.get();
259261

260262
try {
261263
// Convert outputSchema to string
@@ -284,9 +286,9 @@ public McpSchema.CallToolResult callTool(McpSchema.CallToolRequest callToolReque
284286
}
285287
}
286288
catch (JsonProcessingException e) {
287-
// Log error if output schema can't be parsed to prevent erroring out for
288-
// successful call tool request
289-
logger.error("Encountered exception when parsing outputSchema: {}", e);
289+
// Log warning if output schema can't be parsed to prevent erroring out
290+
// for successful call tool request
291+
logger.warn("Failed to validate CallToolResult: Error parsing tool outputSchema: {}", e);
290292
}
291293
}
292294
return result;

0 commit comments

Comments
 (0)