MCPServer: content-block returns are unstructured, prompt messages take Image/Audio (#3320)

This commit is contained in:
Max 2026-08-17 14:12:31 +01:00 • committed by GitHub
commit fb443cc4b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,7 +2,7 @@
import pytest
from inline_snapshot import snapshot
from mcp_types import TextContent
from mcp_types import EmbeddedResource, ImageContent, TextContent, TextResourceContents
from docs_src.structured_output import (
tutorial001,
@ -17,6 +17,7 @@ from docs_src.structured_output import (
)
from mcp import Client
from mcp.server import MCPServer
from mcp.server.mcpserver import Image
from mcp.server.mcpserver.exceptions import InvalidSignature
# See test_index.py for why this is a per-module mark and not a conftest hook.
@ -173,6 +174,36 @@ async def test_structured_output_false_opts_out() -> None:
]
async def test_content_blocks_and_media_are_opted_out_of_structured_output() -> None:
"""The "Content blocks and media" section: a content-block or `Image`/`Audio` return annotation, bare or
as list items, derives no output schema and no structured content; the blocks are the result."""
mcp = MCPServer("Reports")
document = EmbeddedResource(
type="resource", resource=TextResourceContents(uri="report://q3", mime_type="text/markdown", text="# Q3")
)
@mcp.tool()
def report() -> EmbeddedResource:
return document
@mcp.tool()
def chart() -> list[str | Image]:
return ["Sales by region:", Image(data=b"png", format="png")]
async with Client(mcp) as client:
tools = {tool.name: tool for tool in (await client.list_tools()).tools}
assert tools["report"].output_schema is None
assert tools["chart"].output_schema is None
report_result = await client.call_tool("report", {})
assert (report_result.content, report_result.structured_content) == ([document], None)
chart_result = await client.call_tool("chart", {})
assert chart_result.structured_content is None
assert chart_result.content == [
TextContent(type="text", text="Sales by region:"),
ImageContent(type="image", data="cG5n", mime_type="image/png"),
]
async def test_class_without_type_hints_is_silently_unstructured() -> None:
"""tutorial009: a class with no annotations on its body gets no schema, and the model gets a `repr`."""
async with Client(tutorial009.mcp) as client: