Summary
When a tool returns both content and structuredContent with a widget (openai/outputTemplate), the content field is not forwarded to the model. Only structuredContent is passed (as a raw JSON code block), causing the model to miss any info included in content.
Expected Behavior
Per the MCP server documentation:
content – optional narration (Markdown or plaintext) for the model's response.
The widget reads those payloads through window.openai.toolOutput and window.openai.toolResponseMetadata, while the model only sees structuredContent/content.
The model should receive both structuredContent and content, allowing developers to provide a short narration text (e.g., "Found 14 products") that guides the model's response.
Actual Behavior
When a widget renders:
structuredContent is passed to the model as a content_type: "code" block with language: "json"
content is not present in the model's context
_meta is correctly forwarded to tool_response_metadata
- A hidden system message is added: "The tool included embedded UI which has been displayed to the user"
The model then sees the full raw JSON from structuredContent and attempts to summarize it, echoing data (titles, prices, URLs, descriptions) that is already displayed in the widget UI.
Reproduction
MCP Server returns:
return {
content: [{ type: "text", text: "Found 14 products for "jackets"." }],
structuredContent: { products: [...], searches: [...], brand: {...} },
_meta: { apiBaseUrl: "...", subject: null },
};Verified via MCP Inspector:
- "Unstructured Content" shows:
"Found 14 products for "jackets"."
- This confirms the server IS sending
content
Captured ChatGPT SSE stream (/backend-api/f/conversation):
- Tool response message has
content.content_type: "code" with content.text containing only structuredContent fields
- No trace of the
content array text
_meta appears in metadata.chatgpt_sdk.tool_response_metadata (proving MCP response is received)
Impact
- Model loses the
content field, which can have important information
Environment
@modelcontextprotocol/sdk: 1.12.1
- Transport:
StreamableHTTPServerTransport
- Tool has
openai/outputTemplate set (widget renders)
Questions
- Is this intentional behavior when a widget is rendered?
- If so, the documentation should clarify that
content is ignored when openai/outputTemplate is set
- If not, can this be fixed so
content reaches the model alongside structuredContent?
Summary
When a tool returns both
contentandstructuredContentwith a widget (openai/outputTemplate), thecontentfield is not forwarded to the model. OnlystructuredContentis passed (as a raw JSON code block), causing the model to miss any info included incontent.Expected Behavior
Per the MCP server documentation:
The model should receive both
structuredContentandcontent, allowing developers to provide a short narration text (e.g., "Found 14 products") that guides the model's response.Actual Behavior
When a widget renders:
structuredContentis passed to the model as acontent_type: "code"block withlanguage: "json"contentis not present in the model's context_metais correctly forwarded totool_response_metadataThe model then sees the full raw JSON from
structuredContentand attempts to summarize it, echoing data (titles, prices, URLs, descriptions) that is already displayed in the widget UI.Reproduction
MCP Server returns:
return {
content: [{ type: "text", text: "Found 14 products for "jackets"." }],
structuredContent: { products: [...], searches: [...], brand: {...} },
_meta: { apiBaseUrl: "...", subject: null },
};Verified via MCP Inspector:
"Found 14 products for "jackets"."contentCaptured ChatGPT SSE stream (
/backend-api/f/conversation):content.content_type: "code"withcontent.textcontaining onlystructuredContentfieldscontentarray text_metaappears inmetadata.chatgpt_sdk.tool_response_metadata(proving MCP response is received)Impact
contentfield, which can have important informationEnvironment
@modelcontextprotocol/sdk: 1.12.1StreamableHTTPServerTransportopenai/outputTemplateset (widget renders)Questions
contentis ignored whenopenai/outputTemplateis setcontentreaches the model alongsidestructuredContent?