MCP tool call result structure: content, structuredContent

An MCP tool call result has a content array, optional structuredContent, and isError. What goes where, how images travel, and how errors look.

5 min readSume
All posts

An MCP tool call result is a JSON object with three main parts: a content array of items (text, image, audio, resource links, and embedded resources), an optional structuredContent field for machine-readable data, and isError, which is true when the tool itself failed. Images and audio travel as base64 data with a mimeType, and a tool that returns structured data should also put it in a text item as serialized JSON.

The structure comes from the MCP 2025-11-25 tools page and schema reference, with changes from the 2026-07-28 tools page and changelog, all read on 2026-09-28. The worked example is Sume's hosted MCP server, from its current code; Sume's basics page says hosted MCP still works but is not the primary path today.

What fields does a tool call result have?

The result sits in the JSON-RPC response's result. The spec's weather example returns the same data twice, as text and as structuredContent:

From the MCP schema reference (2025-11-25) and the 2026-07-28 changelog, read 2026-09-28.
FieldRequiredWhat it holds
contentYesA list of content objects: the unstructured result of the call
structuredContentNoThe structured result: a JSON object in 2025-11-25, any JSON value in 2026-07-28
isErrorNoWhether the call ended in an error; treated as false when not set
resultTypeYes, from 2026-07-28"complete" for ordinary results; clients treat an older result without it as "complete"
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      { "type": "text", "text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\", \"humidity\": 65}" }
    ],
    "structuredContent": { "temperature": 22.5, "conditions": "Partly cloudy", "humidity": 65 }
  }
}

How do I return an image from an MCP tool?

Add an image item to content: "type": "image", the image as base64 in data, and its mimeType, such as image/png. The schema notes that different providers may support different image types. Every content type can also carry optional annotations for audience, priority, and modification times. The other item types:

  • text: a text string.
  • audio: base64 data and a mimeType, such as audio/wav.
  • resource_link: a uri the client can subscribe to or fetch, with a name, description, and mimeType. The linked resource isn't guaranteed to appear in resources/list.
  • resource: an embedded resource with its uri, mimeType, and contents. Servers that embed resources SHOULD implement the resources capability.

When should I use structuredContent and an outputSchema?

Use structuredContent when a program, not only the model, reads the result. For backwards compatibility, a tool that returns it SHOULD also return the serialized JSON in a text block. The spec calls it server-produced result data, unrelated to LLM structured outputs, which it glosses as schema-constrained model generation.

A tool can also declare an outputSchema. If it does, servers MUST return structured results that conform to it, and clients SHOULD validate them; the spec says this enables strict schema validation and gives type information for better integration with programming languages. In 2025-11-25 the schema's root is restricted to type: "object"; the 2026-07-28 revision loosens inputSchema and outputSchema to any JSON Schema 2020-12 keywords.

How does a tool report an error in the result?

With isError: true and a content item that explains what went wrong. The schema says errors that originate from the tool SHOULD be reported inside the result, not as a protocol-level error, or the model can't see the error and self-correct. Errors in finding the tool, or other exceptional conditions, should be MCP error responses instead; MCP error codes covers those numbers.

What does Sume's MCP server return?

One text item, in current code. On success, Sume's hosted server returns a single text item holding a JSON object, with isError: false, and no structuredContent. Its listed tools carry name, title, description, inputSchema, and annotations, and no outputSchema.

  • A failure is one text item whose JSON has a code and a message, with isError: true.
  • A result over 256 KB is replaced by an isError: true result with the code mcp_output_too_large, which its message calls an output limit, not a job failure: never resubmit a paid create.
  • There are no image or audio items. Generation tools answer with a job id, and a finished job's artifacts carry media.sume.com URLs, which jobs_result returns inside that JSON.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume