1b74b06753
Cut comment and docstring volume roughly in half across src, tests, examples, and docs_src: removed comments that restate the adjacent code, leftover development narration, section banners, and self-evident Args/Returns blocks, and compressed the remaining docstrings to a Google-style summary line plus only the detail that earns its place. Kept (and tightened) the load-bearing content: Raises sections, deprecation and version-availability notes, spec/RFC/issue references, why-comments for non-obvious decisions, and all coverage pragmas. The generated mcp_types.v* wire modules are untouched.
schema-validators
Four ways to type a tool parameter so MCPServer derives the JSON-Schema
inputSchema and validates arguments before your handler runs: a pydantic
BaseModel, a TypedDict, a @dataclass, and a bare dict[str, Any]. The
client lists the tools, resolves each who schema, and round-trips a call.
Run it
# stdio (default — the client spawns the server as a subprocess)
uv run python -m stories.schema_validators.client
# HTTP — the client self-hosts the server on a free port, runs, then tears it down
uv run python -m stories.schema_validators.client --http
# same, against the lowlevel-API server variant
uv run python -m stories.schema_validators.client --http --server server_lowlevel
What to look at
client.pymain— the body opens withasync with Client(target, mode=mode) as client:.targetis anythingClientaccepts (an in-process server, a transport, or an HTTP URL); the entry point picks it, the story constructs it.server.py—who.namevswho["name"]: pydantic and dataclass parameters arrive as instances (attribute access); TypedDict anddict[str, Any]arrive as plain dicts.client.py— the listedinputSchemafor the three typed variants nests a$defs/$refobject with anameproperty;greet_dictpublishes only{"type": "object", "additionalProperties": true}— no field validation.server_lowlevel.py— the same schemas written by hand. There is no reflection layer at this tier; you author JSON Schema and unpackparams.argumentsyourself.
Caveats
- Pydantic emits local
#/$defs/references for nested models. The SDK does not dereference network$refs (SEP-2106 MUST NOT); only same-document refs are resolved during validation. PersonTDistotal=True, so its nested schema requires bothnameandtitle; theBaseModeland@dataclassvariants defaulttitle="friend", so onlynameis required there. Usetyping.NotRequired[...]to mark optional TypedDict fields.
Spec
See also
tools/ (output schema → structuredContent), error_handling/ (what
happens when validation fails).