You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Type the elicitation requested schema on the send side
ElicitRequestedSchema was a TypeAlias for dict[str, Any]; it is now a
Pydantic model of the spec's restricted requested-schema subset, backed
by a new PrimitiveSchemaDefinition union (StringSchema, NumberSchema,
BooleanSchema, and the enum schemas). ServerSession.elicit_form (and the
deprecated elicit alias) and ClientPeer.elicit_form accept only this
model, so a nested-object property, an array-of-objects property, or an
anyOf union is unconstructible at the only place a server author
supplies a schema, rather than silently forwarded to the client.
The spec restricts form-mode requested schemas to flat objects with
primitive-typed properties only ("complex nested structures, arrays of
objects ... are intentionally not supported"). The high-level
Context.elicit / elicit_with_validation path is unchanged in behaviour:
it converts the rendered JSON Schema into the typed model, keeping its
existing per-field TypeError contract and producing value-identical wire
output.
Inbound is deliberately untouched. The wire field
ElicitRequestFormParams.requested_schema stays a plain dict[str, Any],
so older servers that emit anyOf for Optional form fields still reach
the client's elicitation callback. The typed-model-to-wire-dict
conversion lives in one place, ElicitRequestedSchema.to_wire(), which
both send sites call.
The schema family is extra="allow": keys schema.ts does not name (a
top-level title, pattern, exclusiveMinimum, json_schema_extra keys)
still round-trip, because the primitives-only restriction is carried by
the union members' required type literals, not by extra-key rejection.
Copy file name to clipboardExpand all lines: docs/migration.md
+36Lines changed: 36 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -738,6 +738,42 @@ Positional calls (`await ctx.info("hello")`) are unaffected.
738
738
739
739
`Context.elicit()` (and `elicit_with_validation()`) now render the schema first and validate each property against the spec's `PrimitiveSchemaDefinition`, raising `TypeError` at the call site for anything outside it. `Optional[T]` fields render as `{"type": ...}` with the field omitted from `required` (previously the non-spec `anyOf` shape). A bare `list[str]` field is rejected because it renders without the required enum items; use `list[Literal[...]]` or `list[str]` with `json_schema_extra` supplying the items. Unions of multiple primitives (e.g. `int | str`) and nested models are rejected.
740
740
741
+
### `ServerSession.elicit_form()` takes a typed `ElicitRequestedSchema`
742
+
743
+
`ServerSession.elicit_form()` (and the deprecated `elicit()` alias, and `ClientPeer.elicit_form()`)
744
+
now take an `mcp_types.ElicitRequestedSchema` -- a Pydantic model of the spec's restricted
745
+
requested-schema subset -- instead of an arbitrary `dict[str, Any]`. `ElicitRequestedSchema` was
746
+
previously a `TypeAlias` for `dict[str, Any]`; it is now that model. A schema with a nested-object
747
+
property, an array-of-objects property, or an `anyOf` union is rejected at construction.
748
+
749
+
**Why:** the spec restricts form-mode requested schemas to flat objects with primitive-typed
750
+
properties only ("complex nested structures, arrays of objects ... are intentionally not
751
+
supported"). Typing the send side makes a non-conforming schema impossible to construct rather
752
+
than silently forwarded.
753
+
754
+
**How to migrate:** build the model in place of the dict, or validate an existing JSON Schema dict:
755
+
756
+
```python
757
+
from mcp_types import BooleanSchema, ElicitRequestedSchema, StringSchema
0 commit comments