Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ public record RootCapabilities(@JsonProperty("listChanged") Boolean listChanged)
* from MCP servers in their prompts.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Sampling() {
}

Expand Down Expand Up @@ -431,19 +432,22 @@ public record Sampling() {
* @param url support for out-of-band URL-based elicitation
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Elicitation(@JsonProperty("form") Form form, @JsonProperty("url") Url url) {

/**
* Marker record indicating support for form-based elicitation mode.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Form() {
}

/**
* Marker record indicating support for URL-based elicitation mode.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Url() {
}

Expand Down Expand Up @@ -542,13 +546,15 @@ public record ServerCapabilities( // @formatter:off
* Present if the server supports argument autocompletion suggestions.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record CompletionCapabilities() {
}

/**
* Present if the server supports sending log messages to the client.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record LoggingCapabilities() {
}

Expand All @@ -559,6 +565,7 @@ public record LoggingCapabilities() {
* the prompt list
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record PromptCapabilities(@JsonProperty("listChanged") Boolean listChanged) {
}

Expand All @@ -570,6 +577,7 @@ public record PromptCapabilities(@JsonProperty("listChanged") Boolean listChange
* the resource list
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record ResourceCapabilities(@JsonProperty("subscribe") Boolean subscribe,
@JsonProperty("listChanged") Boolean listChanged) {
}
Expand All @@ -581,6 +589,7 @@ public record ResourceCapabilities(@JsonProperty("subscribe") Boolean subscribe,
* the tool list
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record ToolCapabilities(@JsonProperty("listChanged") Boolean listChanged) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1760,4 +1760,75 @@ void testProgressNotificationWithoutMessage() throws Exception {
{"progressToken":"progress-token-789","progress":0.25}"""));
}

// Capability sub-records: unknown fields should be silently ignored (#766)

@Test
void testSamplingIgnoresUnknownFields() throws Exception {
McpSchema.ClientCapabilities.Sampling sampling = JSON_MAPPER.readValue("""
{"futureField": true}""", McpSchema.ClientCapabilities.Sampling.class);
assertThat(sampling).isNotNull();
}

@Test
void testElicitationIgnoresUnknownFields() throws Exception {
McpSchema.ClientCapabilities.Elicitation elicitation = JSON_MAPPER.readValue("""
{"form": {}, "url": {}, "futureField": "value"}""", McpSchema.ClientCapabilities.Elicitation.class);
assertThat(elicitation).isNotNull();
}

@Test
void testElicitationFormIgnoresUnknownFields() throws Exception {
McpSchema.ClientCapabilities.Elicitation.Form form = JSON_MAPPER.readValue("""
{"futureField": 42}""", McpSchema.ClientCapabilities.Elicitation.Form.class);
assertThat(form).isNotNull();
}

@Test
void testElicitationUrlIgnoresUnknownFields() throws Exception {
McpSchema.ClientCapabilities.Elicitation.Url url = JSON_MAPPER.readValue("""
{"futureField": "value"}""", McpSchema.ClientCapabilities.Elicitation.Url.class);
assertThat(url).isNotNull();
}

@Test
void testCompletionCapabilitiesIgnoresUnknownFields() throws Exception {
McpSchema.ServerCapabilities.CompletionCapabilities completions = JSON_MAPPER.readValue("""
{"futureField": true}""", McpSchema.ServerCapabilities.CompletionCapabilities.class);
assertThat(completions).isNotNull();
}

@Test
void testLoggingCapabilitiesIgnoresUnknownFields() throws Exception {
McpSchema.ServerCapabilities.LoggingCapabilities logging = JSON_MAPPER.readValue("""
{"futureField": "value"}""", McpSchema.ServerCapabilities.LoggingCapabilities.class);
assertThat(logging).isNotNull();
}

@Test
void testPromptCapabilitiesIgnoresUnknownFields() throws Exception {
McpSchema.ServerCapabilities.PromptCapabilities prompts = JSON_MAPPER.readValue("""
{"listChanged": true, "futureField": "value"}""",
McpSchema.ServerCapabilities.PromptCapabilities.class);
assertThat(prompts).isNotNull();
assertThat(prompts.listChanged()).isTrue();
}

@Test
void testResourceCapabilitiesIgnoresUnknownFields() throws Exception {
McpSchema.ServerCapabilities.ResourceCapabilities resources = JSON_MAPPER.readValue("""
{"subscribe": true, "listChanged": false, "futureField": 123}""",
McpSchema.ServerCapabilities.ResourceCapabilities.class);
assertThat(resources).isNotNull();
assertThat(resources.subscribe()).isTrue();
assertThat(resources.listChanged()).isFalse();
}

@Test
void testToolCapabilitiesIgnoresUnknownFields() throws Exception {
McpSchema.ServerCapabilities.ToolCapabilities tools = JSON_MAPPER.readValue("""
{"listChanged": true, "futureField": "value"}""", McpSchema.ServerCapabilities.ToolCapabilities.class);
assertThat(tools).isNotNull();
assertThat(tools.listChanged()).isTrue();
}

}