In MCP, what may an elicitation/create requestedSchema contain?
answer
- Deliberately crippled JSON Schema
- One level only
- Primitives, plus a fixed choice
- No objects inside, no lists
- Any client must be able to draw it
basics
~20 sMCP restricts an elicitation/create requestedSchema to a single flat object whose properties are primitives only — string, number, integer, boolean, or an enum. No nested objects, no arrays. That keeps the form renderable by any client.
solid answer
~40 s`requestedSchema` is JSON Schema, but a deliberately crippled subset. It must be one object whose `properties` are primitive types only: `string`, `number`, `integer`, `boolean`, or a string `enum`. Nesting is not allowed — a property whose type is `object` is illegal — and neither are arrays or schema composition such as `$ref` and `oneOf`. `required` may name which flat properties are mandatory, and per-primitive annotations like `description`, `enum`, and simple range or length constraints are fine. The reason is renderability: any client, including a terminal or a voice front end, must be able to turn the schema into a form without understanding the server's domain. This restriction did **not** widen in revision 2026-07-28; if your data is genuinely structured, flatten it into named primitive fields or take it as an ordinary tool argument instead.
code
json · 20 lines{
"type": "object",
"properties": {
"environment": {
"type": "string",
"enum": ["staging", "production"],
"description": "Target environment for the deploy"
},
"replicas": {
"type": "integer",
"minimum": 1,
"maximum": 10
},
"confirm": {
"type": "boolean",
"description": "Proceed with the deploy"
}
},
"required": ["environment", "confirm"]
}go deeper
Remember the headline: one flat object, primitive fields only, no nesting and no arrays. Being able to state that plainly is most of what a screening question wants.
Explain the exact allowed vocabulary — string, number, integer, boolean, enum, plus required — and give the renderability reason: any client must be able to draw the form without knowing your domain.
Show what you do when the data is not flat: flatten into named fields, split into sequential asks, or move it to the tool's own input schema. Mention that the server re-validates whatever comes back.
Frame the restriction as a deliberate interoperability constraint rather than an oversight, and hold the line on it in API design reviews — a schema that only your own client can render breaks every other host.
## Where the schema appears When an MCP server needs input from the human user it raises an `elicitation/create` ask carrying human-readable prompt text and a `requestedSchema`: a JSON Schema object describing the fields it wants back. The client renders that schema as a form, the user fills it in, and the values come back to the server. In revision 2026-07-28 the ask travels inside the interim result of the `tools/call`, `prompts/get` or `resources/read` the server is handling, and the answer arrives on the client's retry — but the schema's shape is the same regardless of how it is carried. ## The rule The schema must be a single flat object. Its `properties` may use only primitive types: - `string` - `number` - `integer` - `boolean` - an `enum` of string values That is the entire vocabulary. Concretely, this means: - **No nesting.** A property whose `type` is `"object"` is not permitted. You cannot ask for `{ "address": { "city": ..., "zip": ... } }`. - **No arrays.** You cannot ask the user for a list of values in one field. - **No composition.** `$ref`, `allOf`, `anyOf`, `oneOf` and recursive definitions have no place here. What *is* allowed alongside the types: `required`, listing which of the flat properties must be supplied; and the descriptive or constraining annotations that apply to a single primitive — a `description` and title for the field label, `enum` for a fixed choice, minimum/maximum on numbers, length limits on strings. These decorate a primitive; they do not introduce structure. ## Why the restriction exists Three reasons, and an interviewer usually wants at least two of them. **Universal renderability.** The client that has to draw this form knows nothing about your server's domain. It may be a desktop app, an IDE panel, a terminal UI, a web chat, or something with no screen at all. A flat list of typed fields maps onto a form, a sequence of prompts, or a set of spoken questions in every one of those. An arbitrary nested schema does not — supporting it would push a full schema-form-generation engine into every client, and clients would diverge in what they actually supported. **Predictable user comprehension.** Elicitation interrupts a person mid-task. A flat set of labelled fields is something they can read and answer in a few seconds. A nested structure with repeated groups is a data-entry application, and that is not what a mid-request interruption should be. **A smaller blast radius.** The schema comes from the server, which the client treats as untrusted content. Keeping the accepted vocabulary tiny keeps the validation surface tiny on both sides: the client validates what the user typed against a handful of primitive rules, and the server validates the returned values again before using them. ## What to do when your data is not flat Three honest options: 1. **Flatten it.** `address_city`, `address_postcode` as separate string properties, joined server-side. Ugly on the wire, perfectly usable on screen. 2. **Ask again.** Multiple sequential elicitations, one per stage — expensive (each is a full round trip and a fresh interruption) but sometimes genuinely the right model, for instance when the second question depends on the first answer. 3. **Do not elicit at all.** Structured input usually belongs in the tool's own `inputSchema`, which is unrestricted JSON Schema and is filled by the model from context in a single call. Reserve elicitation for the values only a human can supply. A fourth option that is *not* available: encoding a nested object as a JSON string in a `string` property. It technically passes the type rule, but it turns the form into a free-text box the user cannot sensibly fill and defeats the purpose of describing a schema at all. ## Validation is still the server's job A well-behaved client validates the user's input against `requestedSchema` before returning it, but the server must not rely on that. The client is a separate program, possibly a different implementation, possibly buggy, possibly hostile. Treat returned values as untrusted input and re-validate them — type, range, and membership in your enum — before they reach a query, a path, or a shell command. ## Version note This describes revision 2026-07-28. The flat primitives-only restriction has held since elicitation was introduced and was *not* relaxed in 2026-07-28; a candidate who says "that was an early limitation, it takes full JSON Schema now" is repeating a common but wrong assumption.
- Your server needs a list of file globs from the user. How do you ask, given the restriction?Not as an array — that is illegal in `requestedSchema`. Ask for a single string field with a documented separator and split it server-side, validating each entry, or reconsider whether this belongs in elicitation at all: a list of globs is usually a tool argument the model can fill from the conversation, and a tool's `inputSchema` has no such restriction.
- If the client validates the user's input against requestedSchema, does the server still need to validate?Yes, always. The client is a separate program that the server does not control — a different vendor's implementation, an older version, or something written to be hostile. Values arriving from it are untrusted input like any other. Re-check types, ranges and enum membership on the server before those values reach a database query, a filesystem path or a subprocess.
- Can a requestedSchema property use a JSON Schema format annotation such as an email or date hint?Annotations that decorate a single primitive are within the spirit of the restriction — they give the client a hint about how to render and pre-validate one string field, without introducing structure. Do not depend on a client honouring any particular hint, though: treat it as presentation help and enforce the real rule on the server when the value comes back.
Think of it as a paper form with a fixed set of labelled boxes rather than a spreadsheet: anyone can fill in the boxes, and any office can print the form, precisely because it has no sub-tables.
saying these in an interview costs you the question
- Says requestedSchema accepts arbitrary JSON Schema
- Nests an object property for a grouped value
- Asks for a list by declaring an array property
- Encodes structure as a JSON string in one field
- Trusts the client's validation and skips server-side checks