Skip to content

Commit 9a63538

Browse files
LucaButBoringtzolov
authored andcommitted
feat: add AudioContent support to MCP schema (#243)
- Add AudioContent record class implementing Annotated and Content interfaces - Update Content sealed interface to permit AudioContent - Add audio type handling in Content.type() method - Include AudioContent in JsonSubTypes annotation for polymorphic deserialization - Add comprehensive tests for AudioContent serialization and deserialization - Update error message test to include audio in known type ids https://github.com/modelcontextprotocol/modelcontextprotocol/blob/c87a0da6d8c2436d56a6398023c80b0562224454/schema/2025-03-26/schema.ts#L987-L1009
1 parent b539b98 commit 9a63538

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,8 +1359,9 @@ public record CompleteCompletion(
13591359
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
13601360
@JsonSubTypes({ @JsonSubTypes.Type(value = TextContent.class, name = "text"),
13611361
@JsonSubTypes.Type(value = ImageContent.class, name = "image"),
1362+
@JsonSubTypes.Type(value = AudioContent.class, name = "audio"),
13621363
@JsonSubTypes.Type(value = EmbeddedResource.class, name = "resource") })
1363-
public sealed interface Content permits TextContent, ImageContent, EmbeddedResource {
1364+
public sealed interface Content permits TextContent, ImageContent, AudioContent, EmbeddedResource {
13641365

13651366
default String type() {
13661367
if (this instanceof TextContent) {
@@ -1369,6 +1370,9 @@ default String type() {
13691370
else if (this instanceof ImageContent) {
13701371
return "image";
13711372
}
1373+
else if (this instanceof AudioContent) {
1374+
return "audio";
1375+
}
13721376
else if (this instanceof EmbeddedResource) {
13731377
return "resource";
13741378
}
@@ -1398,6 +1402,14 @@ public record ImageContent( // @formatter:off
13981402
@JsonProperty("mimeType") String mimeType) implements Content { // @formatter:on
13991403
}
14001404

1405+
@JsonInclude(JsonInclude.Include.NON_ABSENT)
1406+
@JsonIgnoreProperties(ignoreUnknown = true)
1407+
public record AudioContent( // @formatter:off
1408+
@JsonProperty("annotations") Annotations annotations,
1409+
@JsonProperty("data") String data,
1410+
@JsonProperty("mimeType") String mimeType) implements Annotated, Content { // @formatter:on
1411+
}
1412+
14011413
@JsonInclude(JsonInclude.Include.NON_ABSENT)
14021414
@JsonIgnoreProperties(ignoreUnknown = true)
14031415
public record EmbeddedResource( // @formatter:off

mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void testContentDeserializationWrongType() throws Exception {
5959
{"type":"WRONG","text":"XXX"}""", McpSchema.TextContent.class))
6060
.isInstanceOf(InvalidTypeIdException.class)
6161
.hasMessageContaining(
62-
"Could not resolve type id 'WRONG' as a subtype of `io.modelcontextprotocol.spec.McpSchema$TextContent`: known type ids = [image, resource, text]");
62+
"Could not resolve type id 'WRONG' as a subtype of `io.modelcontextprotocol.spec.McpSchema$TextContent`: known type ids = [audio, image, resource, text]");
6363
}
6464

6565
@Test
@@ -84,6 +84,28 @@ void testImageContentDeserialization() throws Exception {
8484
assertThat(imageContent.mimeType()).isEqualTo("image/png");
8585
}
8686

87+
@Test
88+
void testAudioContent() throws Exception {
89+
McpSchema.AudioContent audioContent = new McpSchema.AudioContent(null, "base64encodeddata", "audio/wav");
90+
String value = mapper.writeValueAsString(audioContent);
91+
92+
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
93+
.when(Option.IGNORING_EXTRA_ARRAY_ITEMS)
94+
.isObject()
95+
.isEqualTo(json("""
96+
{"type":"audio","data":"base64encodeddata","mimeType":"audio/wav"}"""));
97+
}
98+
99+
@Test
100+
void testAudioContentDeserialization() throws Exception {
101+
McpSchema.AudioContent audioContent = mapper.readValue("""
102+
{"type":"audio","data":"base64encodeddata","mimeType":"audio/wav"}""", McpSchema.AudioContent.class);
103+
assertThat(audioContent).isNotNull();
104+
assertThat(audioContent.type()).isEqualTo("audio");
105+
assertThat(audioContent.data()).isEqualTo("base64encodeddata");
106+
assertThat(audioContent.mimeType()).isEqualTo("audio/wav");
107+
}
108+
87109
@Test
88110
void testEmbeddedResource() throws Exception {
89111
McpSchema.TextResourceContents resourceContents = new McpSchema.TextResourceContents("resource://test",

0 commit comments

Comments
 (0)