fix: Remove JsonSchema and use a Map for inputSchema to support json schemas dialect (#749)

* feat: remove JsonSchema an use a Map for inputSchema

- Fixes #886

Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
This commit is contained in:
Bilal Oumehdi 2026-04-10 10:32:22 +01:00 • committed by GitHub
commit 95203233c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 72 additions and 45 deletions

View file

@ -1307,7 +1307,9 @@ public final class McpSchema {
* @param additionalProperties Whether additional properties are allowed
* @param defs Schema definitions using the newer $defs keyword
* @param definitions Schema definitions using the legacy definitions keyword
* @deprecated use {@link Map} instead.
*/
@Deprecated
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record JsonSchema( // @formatter:off
@ -1363,7 +1365,7 @@ public final class McpSchema {
@JsonProperty("name") String name,
@JsonProperty("title") String title,
@JsonProperty("description") String description,
@JsonProperty("inputSchema") JsonSchema inputSchema,
@JsonProperty("inputSchema") Map<String, Object> inputSchema,
@JsonProperty("outputSchema") Map<String, Object> outputSchema,
@JsonProperty("annotations") ToolAnnotations annotations,
@JsonProperty("_meta") Map<String, Object> meta) { // @formatter:on
@ -1380,7 +1382,7 @@ public final class McpSchema {
private String description;
private JsonSchema inputSchema;
private Map<String, Object> inputSchema;
private Map<String, Object> outputSchema;
@ -1403,13 +1405,34 @@ public final class McpSchema {
return this;
}
/**
* @deprecated use {@link #inputSchema(Map)} instead.
*/
@Deprecated
public Builder inputSchema(JsonSchema inputSchema) {
Map<String, Object> schema = new HashMap<>();
if (inputSchema.type() != null)
schema.put("type", inputSchema.type());
if (inputSchema.properties() != null)
schema.put("properties", inputSchema.properties());
if (inputSchema.required() != null)
schema.put("required", inputSchema.required());
if (inputSchema.additionalProperties() != null)
schema.put("additionalProperties", inputSchema.additionalProperties());
if (inputSchema.defs() != null)
schema.put("$defs", inputSchema.defs());
if (inputSchema.definitions() != null)
schema.put("definitions", inputSchema.definitions());
return inputSchema(schema);
}
public Builder inputSchema(Map<String, Object> inputSchema) {
this.inputSchema = inputSchema;
return this;
}
public Builder inputSchema(McpJsonMapper jsonMapper, String inputSchema) {
this.inputSchema = parseSchema(jsonMapper, inputSchema);
this.inputSchema = schemaToMap(jsonMapper, inputSchema);
return this;
}
@ -1450,15 +1473,6 @@ public final class McpSchema {
}
}
private static JsonSchema parseSchema(McpJsonMapper jsonMapper, String schema) {
try {
return jsonMapper.readValue(schema, JsonSchema.class);
}
catch (IOException e) {
throw new IllegalArgumentException("Invalid schema: " + schema, e);
}
}
/**
* Used by the client to call a tool provided by the server.
*

View file

@ -4,6 +4,8 @@
package io.modelcontextprotocol.server;
import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA;
import java.util.List;
import java.util.Map;
@ -25,7 +27,6 @@ import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

View file

@ -4,6 +4,8 @@
package io.modelcontextprotocol.server;
import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA;
import java.util.List;
import java.util.Map;
@ -22,7 +24,6 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

View file

@ -1,15 +1,14 @@
package io.modelcontextprotocol.util;
import io.modelcontextprotocol.spec.McpSchema;
import java.util.Collections;
import java.util.Map;
public final class ToolsUtils {
private ToolsUtils() {
}
public static final McpSchema.JsonSchema EMPTY_JSON_SCHEMA = new McpSchema.JsonSchema("object",
Collections.emptyMap(), null, null, null, null);
public static final Map<String, Object> EMPTY_JSON_SCHEMA = Map.of("type", "object", "properties",
Collections.emptyMap());
}