Hand TypedDict tool results to pydantic natively (#3331)

This commit is contained in:
Max 2026-08-20 15:36:21 +01:00 • committed by GitHub
commit 0cee6249ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -44,6 +44,7 @@ from mcp_types import (
from pydantic import BaseModel
from starlette.applications import Starlette
from starlette.routing import Mount, Route
from typing_extensions import NotRequired, TypedDict
from mcp.client import Client
from mcp.server.context import ServerRequestContext
@ -715,6 +716,32 @@ class TestServerTools:
assert "Unknown tool" in content.text
async def test_typeddict_tool_omitting_optional_keys_passes_client_validation():
"""The client validates structured content against the tool's output schema, so a `NotRequired`
key the tool leaves out must be absent from `structured_content` rather than null."""
class Person(TypedDict):
name: str
age: NotRequired[int]
mcp = MCPServer()
@mcp.tool()
def get_person() -> Person:
return {"name": "Dave"}
async with Client(mcp) as client:
(tool,) = (await client.list_tools()).tools
assert tool.output_schema == {
"type": "object",
"title": "Person",
"properties": {"name": {"title": "Name", "type": "string"}, "age": {"title": "Age", "type": "integer"}},
"required": ["name"],
}
result = await client.call_tool("get_person", {})
assert result.structured_content == {"name": "Dave"}
class TestServerResources:
async def test_init_with_resources(self):
def get_text() -> str: