Skip to content

mcp: don't omit required fields in ImageContent and AudioContent #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

martinemde
Copy link
Contributor

@martinemde martinemde commented Jul 4, 2025

This is a follow-up related to #91 (though not requiring it).

Updates ImageContent and AudioContent to use an inline wire format to ensure that required fields are not omitted during JSON marshaling, matching TypeScript schema requirements. This follows the TextContent approach.

  • ImageContent requires data and mimeType fields.
  • AudioContent requires data and mimeType fields.

findleyr pushed a commit that referenced this pull request Jul 4, 2025
I noticed this while working on #95. Seems Meta was accidentally skipped
in the custom wire format struct.
@findleyr
Copy link
Contributor

findleyr commented Jul 7, 2025

@martinemde I think your suggestion to remove the 'omitempty' attrs is preferable: the missing 'mimeType' or 'data' field is really an error in business logic, not marshalling.

For data, we should be careful to replace nil with an empty byte slice, as JSON null is not valid.

Thanks for picking this up!

mcp/content.go Outdated
}
if c.MIMEType == "" {
return nil, errors.New("ImageContent missing mimeType")
}
return json.Marshal(&wireContent{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted, I think we should use an inline type rather than 'wireContent' here, so that we can make Data and MimeType not "omitempty". We should be sure to replace nil data with the empty slice though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a requested change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will get to it asap.

mcp/content.go Outdated
}
if c.MIMEType == "" {
return nil, errors.New("ImageContent missing mimeType")
}
return json.Marshal(&wireContent{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a requested change.

@martinemde martinemde force-pushed the martinemde/validate-required-content-fields branch from 3b9ca9b to 9091440 Compare July 16, 2025 23:16
@martinemde
Copy link
Contributor Author

This is updated. Thanks for your patience while I got around to this.

@martinemde martinemde changed the title mcp: validate required fields in ImageContent and AudioContent mcp: don't omit required fields in ImageContent and AudioContent Jul 16, 2025
@martinemde martinemde force-pushed the martinemde/validate-required-content-fields branch from 9091440 to ef96b43 Compare July 16, 2025 23:20
…Content

ImageContent and AudioContent now use custom MarshalJSON methods with
inline structs to ensure data and mimeType fields are always included
in JSON output, even when empty. This matches the approach used for
TextContent.Text and follows TypeScript schema requirements.

Updated tests to verify empty fields are serialized as empty strings
rather than being omitted.
@martinemde martinemde force-pushed the martinemde/validate-required-content-fields branch from ef96b43 to c5b9f06 Compare July 16, 2025 23:23
@@ -58,13 +58,25 @@ type ImageContent struct {
}

func (c *ImageContent) MarshalJSON() ([]byte, error) {
return json.Marshal(&wireContent{
// Custom wire format to ensure required fields are always included, even when empty.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like these two functions are almost identical. Factor out into a single function. It looks to me that that function's args are the type (image or audio) and the data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can if you think it's important.

Two copies of something doesn't feel like a strong deduplication signal to me given that it will split the currently very clear schema mapping into a function that abstracts away half of the type.

If you think this is a blocker, I'll refactor, since I'd prefer the sdk is correct regardless of the code inside.

@jba jba merged commit dced3e4 into modelcontextprotocol:main Jul 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants