That asymmetry is why this page exists. The specification requires a server to conform to any output schema it declares, and only advises the client to check. So the party obliged to be correct is not the party obliged to notice, and a server that drifts from its own schema breaks nothing visibly: the result flows through, and something downstream reads a field that is not the shape it was promised.
outputSchema describes structuredContent, not the result
This is the mistake that produces a schema which can never match. The envelope is content, structuredContent and isError. The schema describes the contents of structuredContent alone, so a schema whose properties include content or isError is one level too high and will fail against every result the server ever returns. It looks entirely reasonable in review, which is why it survives.
The text block almost nobody emits
The specification says a tool returning structured content SHOULD also return the serialized JSON in a TextContent block. It is a SHOULD, so skipping it breaks no rule, and the consequence is invisible: a client that does not read structuredContent gets a result whose content array is empty or full of prose. The tool ran, the data came back, and the model was handed nothing. This page checks that the block exists AND that it carries the same data, because a mirror that disagrees is worse than one that is missing.