Canonical: https://botbento.com/blog/mcp-tool-output-schema-validation/
Format: Markdown representation of the public HTML page.

[Home](/) / [Blog](/blog/)

FIELD NOTES / 4 MIN READ

# MCP Tools Can Declare an Output Schema. Should Your Bot Validate It?

MCP tool definitions can declare an outputSchema and successful results can carry structuredContent. A bot should check that result against the declared schema before acting on it, while handling tool execution errors and request failures on their own paths.

By BotBento Editorial · Published 2026-09-29 · Updated 2026-09-29

AI-assisted editorial: researched and drafted with AI using the primary sources linked below. Examples are illustrative; they are not measured product results. [Editorial policy](/editorial/).

## In this article

- [What actually changed in the tool result](#what-changed)
- [Shape is a different question from success](#shape-vs-success)
- [A worked example (illustrative)](#worked-example)
- [Where this breaks in practice](#failure-paths)
- [The decision](#the-decision)[Read as Markdown ](/text/blog/mcp-tool-output-schema-validation/index.md)

## Key takeaways

- outputSchema describes the expected shape of structuredContent; isError flags a tool execution error in a returned tool result, while transport or protocol failures may have no tool result to inspect.
- For a successful call to a tool that declares outputSchema, treat absent or nonconforming structuredContent as a result-contract failure before acting on the data.
- Keep a documented path for tools without outputSchema; do not use an unvalidated text block to bypass a failed structured-result check.

## What actually changed in the tool result

MCP tools may return a content array with text or other blocks, and a Tool definition may include an optional outputSchema alongside inputSchema. The 2025-11-25 tools specification already defines outputSchema and structuredContent; they are not newly introduced by the 2026 revision. A weather tool, for example, can return a human-readable summary and structured JSON so a client need not parse prose to find the temperature.

The 2026-07-28 specification expands what those fields can express. Its output schemas support full JSON Schema 2020-12, and structuredContent can be any JSON value, including an array or a scalar, rather than only an object. The specification says implementations must not automatically dereference external $ref URIs and should bound schema depth and validation time.

The useful promise is an expected, machine-readable result shape. It does not prove the data is true or that the operation was authorized; clients still need their ordinary trust and action checks.

Sources: [Tools - Model Context Protocol (2025-11-25)](https://modelcontextprotocol.io/specification/2025-11-25/server/tools), [Tools - Model Context Protocol (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools).

## Shape is a different question from success

A returned tool result can use isError: true to report a tool execution error, such as an underlying API failure or invalid input. A request timeout, transport failure, or JSON-RPC protocol error may instead leave the caller without a CallToolResult at all. Handle those request failures before examining result fields; isError is not a universal success signal for every attempted call.

For a completed, non-error result, outputSchema and structuredContent answer a different question: does the returned JSON match the shape the tool advertised? A server can return a non-error result with a missing required field or a renamed property. If the client passes it downstream without validation, the next action may break or use the wrong value. The tools specification says servers with an outputSchema must provide conforming structured results and clients should validate them.

Sources: [Tools - Model Context Protocol (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools).

## A worked example (illustrative)

Say a bot calls a fictional invoice-lookup tool. The tool's listing declares an outputSchema requiring amount\_cents (integer), currency (string), and status (one of paid, pending, overdue). On a normal call, the result carries a content block with a human-readable summary and a structuredContent object matching that shape: \{"amount\_cents": 4200, "currency": "USD", "status": "pending"}.

Now suppose the invoice service changes its API and the tool handler starts returning status as a nested object (\{"code": "pending", "label": "Awaiting payment"}) without updating its declared outputSchema. The call returns a non-error result, but structuredContent no longer matches the advertised schema. A bot that assumes status is a string may reject the value too late or pass the wrong shape to a later step.

Before using structuredContent, check that it is present for a successful result when the tool declares outputSchema, then validate it with a JSON Schema validator configured for the declared dialect and bounded reference resolution. On mismatch, log the contract failure and avoid acting on that data. A text block from the same response is not a safe bypass unless the tool has a separately documented fallback contract that you validate too. Retrying unchanged may return the same malformed value; route the mismatch to the tool owner when appropriate.

## Where this breaks in practice

One failure path is validating an error result as though it were a successful structured result. When isError is true, handle the tool execution error first; an error response may be text meant for recovery rather than the success payload described by outputSchema. Keep request or transport failures, which may produce no tool result, on a separate path.

Another failure path is asymmetric adoption. A tool without outputSchema may return only content blocks. A bot that assumes structured output everywhere will break on those tools. Keep a documented text-handling path for tools that do not advertise an output schema, while requiring schema validation for successful structured responses from tools that do.

A third failure path is treating schema validation as a security boundary. It only checks shape. A tool can return a schema-conforming value that is false, stale, or unsafe to use. Keep authorization, provenance, and sanity checks independent of output validation.

## The decision

When a tool advertises outputSchema, first determine whether the request returned a tool result. Handle request failures and isError tool errors separately. For a successful result, require structuredContent and validate it against the declared schema before the bot acts on it. When a tool has no outputSchema, use the tool’s documented content contract rather than inventing a schema it never promised.

This prevents a bot from quietly acting on data that does not match the tool’s advertised shape. Validation is one check in the result path, alongside the existing authorization and trust checks; it cannot turn untrusted tool data into a verified fact.

## Primary sources

Sources checked 2026-09-29. Standards and product documentation can change; follow the linked version when implementing.

- [Tools - Model Context Protocol (2025-11-25)](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) — Model Context Protocol
- [Tools - Model Context Protocol (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools) — Model Context Protocol

BotBento is in development. [Suggest a correction](/contact/).
