What is EnumSchema?
EnumSchema is the MCP elicitation type for constrained choice inputs — situations where a user must pick from a fixed set of options rather than entering freeform text. It covers four concrete shapes: untitled single-select (type: "string" plus an enum array), titled single-select (adds enumNames for display labels), untitled multi-select (type: "array" with items.enum), and titled multi-select (items.enum paired with items.enumNames). The type discriminator is the top-level "type" field: "string" for single-select and "array" for multi-select.\n\nIn the MCP message flow, EnumSchema appears inside elicitation request parameters when a server needs the client to collect structured user input before continuing a tool call or sampling turn. The server sends the schema; the MCP client renders an appropriate UI widget (dropdown, radio group, checkbox list) and returns the chosen value or values. Because the enum is declared server-side and validated client-side, the constraint is advisory rather than cryptographically enforced — servers must re-validate the returned value against the original enum array.\n\nThe optional minItems and maxItems fields apply only to multi-select (type: "array") and let the server express cardinality requirements such as "choose at least one" or "pick exactly two". The default field accepts either a single string or an array of strings matching the declared shape, and a well-formed default must itself be a member of the enum array. There are no version-gated fields here — EnumSchema was present from the first stable elicitation draft and has not changed its surface since.
When to use
In elicitation forms for dropdowns and checkbox groups.
When NOT to use
For free-text input — use StringSchema.
Notes
enumNames are display-only, not returned
When you supply enumNames alongside enum, the client renders the human-readable label but always returns the corresponding enum value string in the response. Never design your server logic to receive the label — it will only ever see the raw enum member. If enumNames and enum arrays have mismatched lengths the behaviour is undefined and most SDK clients will silently truncate or ignore the extra labels.
Re-validate returned values server-side
The MCP spec does not require clients to enforce enum membership before returning a response — a buggy or malicious client can return any string. Always check that the returned value is a member of your original enum array before using it in tool logic, SQL queries, or API calls. This is especially important when enum values map to internal identifiers or permission scopes.
minItems and maxItems only apply to array type
Setting minItems or maxItems on a single-select schema (type: "string") is a no-op and some SDK validators will emit a warning. Keep cardinality constraints in sync with the type field. If you want exactly-one semantics on a multi-select, set both minItems: 1 and maxItems: 1, but consider whether single-select better expresses the intent.
Default must be a valid enum member
A default value that is not present in the enum array is a schema authoring error. Some clients will silently drop an invalid default and render no pre-selection; others may throw during form initialisation. For multi-select defaults, every element of the default array must individually appear in items.enum. Validate your schema constants in unit tests rather than relying on runtime client rejection.
Enum size affects client rendering performance
Very large enum arrays (hundreds of options) can cause client UI widgets to render slowly or become unusable as dropdowns. MCP does not define a hard cap, but practical experience puts the comfortable limit around 50–100 entries. If your option set is larger, consider a StringSchema with server-side autocomplete or splitting into hierarchical calls instead of a flat enum.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| type | 'string' | 'array' | yes | string for single-select, array for multi-select. |
| enum | string[] | yes | Allowed values (or items.enum for multi-select). |
| minItems | number? | no | Multi-select only. |
| maxItems | number? | no | Multi-select only. |
| default | string | string[]? | no | Default selection. |
Examples
Single-select
{ "type": "string", "enum": ["small", "medium", "large"], "default": "medium" }
Common mistakes
❌ Forgetting items.enum on multi-select
✅ Multi-select needs items: { type: 'string', enum: [...] }.