What is structured tool output, and how does it differ from plain text content?
Quick Answer
By default, a CallToolResult's content array holds unstructured content blocks (text, image, audio, or an embedded resource) meant for a human or the model to read directly. Structured content (structuredContent, added alongside an optional outputSchema on the tool definition) lets a tool additionally return a JSON object that conforms to a declared schema, giving hosts and downstream code a machine-parseable result instead of forcing them to parse text. A weather tool, for example, can return both a human-readable text summary and a structured {'tempF': 91, 'condition': 'sunny'} object in the same result, so a host that wants to render a custom widget doesn't have to regex-parse prose to get the temperature.
Detailed Answer
Plain-text tool results are easy to hand to a model. They're painful for a host that wants to do something programmatic with the result, not just display it.
Before: text-only result
{"content": [{"type": "text", "text": "Austin: 91F, sunny, 62% humidity"}]}
A host that wants to render a weather widget now has to parse this string. That's fragile against any wording change.
With structured output
// Tool definition declares an outputSchema
{
"name": "get_weather",
"inputSchema": {...},
"outputSchema": {
"type": "object",
"properties": {
"tempF": {"type": "number"},
"condition": {"type": "string"},
"humidityPct": {"type": "number"}
},
"required": ["tempF", "condition"]
}
}
// CallToolResult returns both
{
"content": [{"type": "text", "text": "Austin: 91F, sunny, 62% humidity"}],
"structuredContent": {"tempF": 91, "condition": "sunny", "humidityPct": 62}
}
Why both, not just structured
The content array stays the primary channel the model reads — natural language is still what an LLM reasons over best. structuredContent is additive. It's aimed at the host application and any other non-model consumer that wants to render a chart, populate a form, or feed the value into further deterministic logic without an LLM in the loop. A server that declares outputSchema is also making a validatable promise: hosts can check structuredContent against that schema to catch a malfunctioning tool, the same way inputSchema lets a server catch malformed input.
When to bother
Add structured output when you expect non-model consumers of the result — a UI widget, a downstream automation, a host feature like data visualization. A tool whose result is only ever read by the model in prose form doesn't need it.