# 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

```bash
# 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.py` `main` — the body opens with `async with Client(target, mode=mode)
  as client:`. `target` is anything `Client` accepts (an in-process server, a
  transport, or an HTTP URL); the entry point picks it, the story constructs it.
- `server.py` — `who.name` vs `who["name"]`: pydantic and dataclass parameters
  arrive as **instances** (attribute access); TypedDict and `dict[str, Any]`
  arrive as plain dicts.
- `client.py` — the listed `inputSchema` for the three typed variants nests a
  `$defs`/`$ref` object with a `name` property; `greet_dict` publishes 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 unpack
  `params.arguments` yourself.

## Caveats

- Pydantic emits local `#/$defs/` references for nested models. The SDK does
  not dereference network `$ref`s (SEP-2106 MUST NOT); only same-document refs
  are resolved during validation.
- `PersonTD` is `total=True`, so its nested schema requires both `name` and
  `title`; the `BaseModel` and `@dataclass` variants default `title="friend"`,
  so only `name` is required there. Use `typing.NotRequired[...]` to mark
  optional TypedDict fields.

## Spec

[Tools — input schema](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#input-schema)

## See also

`tools/` (output schema → `structuredContent`), `error_handling/` (what
happens when validation fails).
