Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 726fe3b

Browse files
committedMar 17, 2025
feat(mcp): relax MCP Schema JSON deserialization constraints (#37)
* feat(mcp): relax MCP Schema JSON deserialization constraints - Add @JsonIgnoreProperties(ignoreUnknown = true) annotation to all record classes in McpSchema to make JSON deserialization more robust by ignoring unknown properties. - Make the JsonSchema record public Resolves #36 This improves compatibility with third-party implementations like Cursor that are not MCP Schema compliant. Signed-off-by: Christian Tzolov <[email protected]>
1 parent 0f65c6c commit 726fe3b

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed
 

‎mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java

+32-2
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCNotificati
176176
}
177177

178178
@JsonInclude(JsonInclude.Include.NON_ABSENT)
179+
@JsonIgnoreProperties(ignoreUnknown = true)
179180
public record JSONRPCRequest( // @formatter:off
180181
@JsonProperty("jsonrpc") String jsonrpc,
181182
@JsonProperty("method") String method,
@@ -184,20 +185,23 @@ public record JSONRPCRequest( // @formatter:off
184185
} // @formatter:on
185186

186187
@JsonInclude(JsonInclude.Include.NON_ABSENT)
188+
@JsonIgnoreProperties(ignoreUnknown = true)
187189
public record JSONRPCNotification( // @formatter:off
188190
@JsonProperty("jsonrpc") String jsonrpc,
189191
@JsonProperty("method") String method,
190192
@JsonProperty("params") Map<String, Object> params) implements JSONRPCMessage {
191193
} // @formatter:on
192194

193195
@JsonInclude(JsonInclude.Include.NON_ABSENT)
196+
@JsonIgnoreProperties(ignoreUnknown = true)
194197
public record JSONRPCResponse( // @formatter:off
195198
@JsonProperty("jsonrpc") String jsonrpc,
196199
@JsonProperty("id") Object id,
197200
@JsonProperty("result") Object result,
198201
@JsonProperty("error") JSONRPCError error) implements JSONRPCMessage {
199202

200203
@JsonInclude(JsonInclude.Include.NON_ABSENT)
204+
@JsonIgnoreProperties(ignoreUnknown = true)
201205
public record JSONRPCError(
202206
@JsonProperty("code") int code,
203207
@JsonProperty("message") String message,
@@ -209,6 +213,7 @@ public record JSONRPCError(
209213
// Initialization
210214
// ---------------------------
211215
@JsonInclude(JsonInclude.Include.NON_ABSENT)
216+
@JsonIgnoreProperties(ignoreUnknown = true)
212217
public record InitializeRequest( // @formatter:off
213218
@JsonProperty("protocolVersion") String protocolVersion,
214219
@JsonProperty("capabilities") ClientCapabilities capabilities,
@@ -239,6 +244,7 @@ public record InitializeResult( // @formatter:off
239244
*
240245
*/
241246
@JsonInclude(JsonInclude.Include.NON_ABSENT)
247+
@JsonIgnoreProperties(ignoreUnknown = true)
242248
public record ClientCapabilities( // @formatter:off
243249
@JsonProperty("experimental") Map<String, Object> experimental,
244250
@JsonProperty("roots") RootCapabilities roots,
@@ -253,7 +259,8 @@ public record ClientCapabilities( // @formatter:off
253259
* @param listChanged Whether the client would send notification about roots
254260
* has changed since the last time the server checked.
255261
*/
256-
@JsonInclude(JsonInclude.Include.NON_ABSENT)
262+
@JsonInclude(JsonInclude.Include.NON_ABSENT)
263+
@JsonIgnoreProperties(ignoreUnknown = true)
257264
public record RootCapabilities(
258265
@JsonProperty("listChanged") Boolean listChanged) {
259266
}
@@ -303,6 +310,7 @@ public ClientCapabilities build() {
303310
}// @formatter:on
304311

305312
@JsonInclude(JsonInclude.Include.NON_ABSENT)
313+
@JsonIgnoreProperties(ignoreUnknown = true)
306314
public record ServerCapabilities( // @formatter:off
307315
@JsonProperty("experimental") Map<String, Object> experimental,
308316
@JsonProperty("logging") LoggingCapabilities logging,
@@ -375,6 +383,7 @@ public ServerCapabilities build() {
375383
} // @formatter:on
376384

377385
@JsonInclude(JsonInclude.Include.NON_ABSENT)
386+
@JsonIgnoreProperties(ignoreUnknown = true)
378387
public record Implementation(// @formatter:off
379388
@JsonProperty("name") String name,
380389
@JsonProperty("version") String version) {
@@ -413,6 +422,7 @@ public interface Annotated {
413422
* optional. It is a number between 0 and 1.
414423
*/
415424
@JsonInclude(JsonInclude.Include.NON_ABSENT)
425+
@JsonIgnoreProperties(ignoreUnknown = true)
416426
public record Annotations( // @formatter:off
417427
@JsonProperty("audience") List<Role> audience,
418428
@JsonProperty("priority") Double priority) {
@@ -458,6 +468,7 @@ public record Resource( // @formatter:off
458468
* @see <a href="https://datatracker.ietf.org/doc/html/rfc6570">RFC 6570</a>
459469
*/
460470
@JsonInclude(JsonInclude.Include.NON_ABSENT)
471+
@JsonIgnoreProperties(ignoreUnknown = true)
461472
public record ResourceTemplate( // @formatter:off
462473
@JsonProperty("uriTemplate") String uriTemplate,
463474
@JsonProperty("name") String name,
@@ -481,6 +492,7 @@ public record ListResourceTemplatesResult( // @formatter:off
481492
} // @formatter:on
482493

483494
@JsonInclude(JsonInclude.Include.NON_ABSENT)
495+
@JsonIgnoreProperties(ignoreUnknown = true)
484496
public record ReadResourceRequest( // @formatter:off
485497
@JsonProperty("uri") String uri){
486498
} // @formatter:on
@@ -499,11 +511,13 @@ public record ReadResourceResult( // @formatter:off
499511
* it is up to the server how to interpret it.
500512
*/
501513
@JsonInclude(JsonInclude.Include.NON_ABSENT)
514+
@JsonIgnoreProperties(ignoreUnknown = true)
502515
public record SubscribeRequest( // @formatter:off
503516
@JsonProperty("uri") String uri){
504517
} // @formatter:on
505518

506519
@JsonInclude(JsonInclude.Include.NON_ABSENT)
520+
@JsonIgnoreProperties(ignoreUnknown = true)
507521
public record UnsubscribeRequest( // @formatter:off
508522
@JsonProperty("uri") String uri){
509523
} // @formatter:on
@@ -574,6 +588,7 @@ public record BlobResourceContents( // @formatter:off
574588
* @param arguments A list of arguments to use for templating the prompt.
575589
*/
576590
@JsonInclude(JsonInclude.Include.NON_ABSENT)
591+
@JsonIgnoreProperties(ignoreUnknown = true)
577592
public record Prompt( // @formatter:off
578593
@JsonProperty("name") String name,
579594
@JsonProperty("description") String description,
@@ -588,6 +603,7 @@ public record Prompt( // @formatter:off
588603
* @param required Whether this argument must be provided.
589604
*/
590605
@JsonInclude(JsonInclude.Include.NON_ABSENT)
606+
@JsonIgnoreProperties(ignoreUnknown = true)
591607
public record PromptArgument( // @formatter:off
592608
@JsonProperty("name") String name,
593609
@JsonProperty("description") String description,
@@ -604,6 +620,7 @@ public record PromptArgument( // @formatter:off
604620
* @param content The content of the message of type {@link Content}.
605621
*/
606622
@JsonInclude(JsonInclude.Include.NON_ABSENT)
623+
@JsonIgnoreProperties(ignoreUnknown = true)
607624
public record PromptMessage( // @formatter:off
608625
@JsonProperty("role") Role role,
609626
@JsonProperty("content") Content content) {
@@ -630,6 +647,7 @@ public record ListPromptsResult( // @formatter:off
630647
* @param arguments Arguments to use for templating the prompt.
631648
*/
632649
@JsonInclude(JsonInclude.Include.NON_ABSENT)
650+
@JsonIgnoreProperties(ignoreUnknown = true)
633651
public record GetPromptRequest(// @formatter:off
634652
@JsonProperty("name") String name,
635653
@JsonProperty("arguments") Map<String, Object> arguments) implements Request {
@@ -667,7 +685,7 @@ public record ListToolsResult( // @formatter:off
667685

668686
@JsonInclude(JsonInclude.Include.NON_ABSENT)
669687
@JsonIgnoreProperties(ignoreUnknown = true)
670-
record JsonSchema( // @formatter:off
688+
public record JsonSchema( // @formatter:off
671689
@JsonProperty("type") String type,
672690
@JsonProperty("properties") Map<String, Object> properties,
673691
@JsonProperty("required") List<String> required,
@@ -688,6 +706,7 @@ record JsonSchema( // @formatter:off
688706
* arguments before sending them to the server.
689707
*/
690708
@JsonInclude(JsonInclude.Include.NON_ABSENT)
709+
@JsonIgnoreProperties(ignoreUnknown = true)
691710
public record Tool( // @formatter:off
692711
@JsonProperty("name") String name,
693712
@JsonProperty("description") String description,
@@ -742,6 +761,7 @@ public record CallToolResult( // @formatter:off
742761
// Sampling Interfaces
743762
// ---------------------------
744763
@JsonInclude(JsonInclude.Include.NON_ABSENT)
764+
@JsonIgnoreProperties(ignoreUnknown = true)
745765
public record ModelPreferences(// @formatter:off
746766
@JsonProperty("hints") List<ModelHint> hints,
747767
@JsonProperty("costPriority") Double costPriority,
@@ -750,17 +770,20 @@ public record ModelPreferences(// @formatter:off
750770
} // @formatter:on
751771

752772
@JsonInclude(JsonInclude.Include.NON_ABSENT)
773+
@JsonIgnoreProperties(ignoreUnknown = true)
753774
public record ModelHint(@JsonProperty("name") String name) {
754775
}
755776

756777
@JsonInclude(JsonInclude.Include.NON_ABSENT)
778+
@JsonIgnoreProperties(ignoreUnknown = true)
757779
public record SamplingMessage(// @formatter:off
758780
@JsonProperty("role") Role role,
759781
@JsonProperty("content") Content content) {
760782
} // @formatter:on
761783

762784
// Sampling and Message Creation
763785
@JsonInclude(JsonInclude.Include.NON_ABSENT)
786+
@JsonIgnoreProperties(ignoreUnknown = true)
764787
public record CreateMessageRequest(// @formatter:off
765788
@JsonProperty("messages") List<SamplingMessage> messages,
766789
@JsonProperty("modelPreferences") ModelPreferences modelPreferences,
@@ -837,6 +860,7 @@ public CreateMessageResult build() {
837860
// Pagination Interfaces
838861
// ---------------------------
839862
@JsonInclude(JsonInclude.Include.NON_ABSENT)
863+
@JsonIgnoreProperties(ignoreUnknown = true)
840864
public record PaginatedRequest(@JsonProperty("cursor") String cursor) {
841865
}
842866

@@ -848,6 +872,7 @@ public record PaginatedResult(@JsonProperty("nextCursor") String nextCursor) {
848872
// ---------------------------
849873
// Progress and Logging
850874
// ---------------------------
875+
@JsonIgnoreProperties(ignoreUnknown = true)
851876
public record ProgressNotification(// @formatter:off
852877
@JsonProperty("progressToken") String progressToken,
853878
@JsonProperty("progress") double progress,
@@ -864,6 +889,7 @@ public record ProgressNotification(// @formatter:off
864889
* @param logger The logger that generated the message.
865890
* @param data JSON-serializable logging data.
866891
*/
892+
@JsonIgnoreProperties(ignoreUnknown = true)
867893
public record LoggingMessageNotification(// @formatter:off
868894
@JsonProperty("level") LoggingLevel level,
869895
@JsonProperty("logger") String logger,
@@ -980,6 +1006,7 @@ else if (this instanceof EmbeddedResource) {
9801006
}
9811007

9821008
@JsonInclude(JsonInclude.Include.NON_ABSENT)
1009+
@JsonIgnoreProperties(ignoreUnknown = true)
9831010
public record TextContent( // @formatter:off
9841011
@JsonProperty("audience") List<Role> audience,
9851012
@JsonProperty("priority") Double priority,
@@ -991,6 +1018,7 @@ public TextContent(String content) {
9911018
}
9921019

9931020
@JsonInclude(JsonInclude.Include.NON_ABSENT)
1021+
@JsonIgnoreProperties(ignoreUnknown = true)
9941022
public record ImageContent( // @formatter:off
9951023
@JsonProperty("audience") List<Role> audience,
9961024
@JsonProperty("priority") Double priority,
@@ -999,6 +1027,7 @@ public record ImageContent( // @formatter:off
9991027
}
10001028

10011029
@JsonInclude(JsonInclude.Include.NON_ABSENT)
1030+
@JsonIgnoreProperties(ignoreUnknown = true)
10021031
public record EmbeddedResource( // @formatter:off
10031032
@JsonProperty("audience") List<Role> audience,
10041033
@JsonProperty("priority") Double priority,
@@ -1019,6 +1048,7 @@ public record EmbeddedResource( // @formatter:off
10191048
* for referencing the root in other parts of the application.
10201049
*/
10211050
@JsonInclude(JsonInclude.Include.NON_ABSENT)
1051+
@JsonIgnoreProperties(ignoreUnknown = true)
10221052
public record Root( // @formatter:off
10231053
@JsonProperty("uri") String uri,
10241054
@JsonProperty("name") String name) {

0 commit comments

Comments
 (0)
Please sign in to comment.