Skip to content

Response content is silently exchanged when structured content is not a hash #467

Description

@NobodysNightmare

Describe the bug
We use the MCP gem in OpenProject. Two things relevant in this context:

  • We use the representable gem for JSON representation of models widely
  • We offer options to enable content, structured content or both to server administrators (the default is to render both)
    • mostly because implementations across MCP clients vary a lot and some would expose the presence of both values twice to their underlying LLM
    • as far as I can tell, this does not violate any MUST requirements of the MCP specification (it definitely violates a few SHOULD requirements)

With the update of mcp from 0.21 to 0.23 our tests started failing, because in some cases the content would not be empty when we expected it to be.

Essentially serialize_structured_content_fallback fails to recognize that we would render a JSON object, because structured.is_a?(Hash) returns false. Indeed structured is not a hash, but it's a representable that will end up as a JSON object. The current workaround I am going to implement is this:

structured_content = JSON.parse(structured_content.to_json)

To Reproduce
Oversimplified reproduction goes via rendering this response:

MCP::Tool::Response.new([], structured_content: { something: 42 })

Expected behavior
As long as a valid content was passed into the response, I'd expect that this is rendered out as-is. The interface of MCP::Tool::Response doesn't usually allow me to only pass the structured_content and get content "auto-filled", so it's surprising if that happens under overly-specific circumstances.

In other words: The MCP::Response interface suggests that I have full control over the response format, but sometimes it takes that control away from me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions