Skip to content

Add MCP::Elicitation::EnumSchema builders for SEP-1330 - #482

Open
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:elicitation_enum_schema
Open

Add MCP::Elicitation::EnumSchema builders for SEP-1330#482
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:elicitation_enum_schema

Conversation

@koic

@koic koic commented Aug 5, 2026

Copy link
Copy Markdown
Member

Motivation and Context

MCP 2025-11-25 (SEP-1330) replaces the ad-hoc enumNames convention with four standards-based enum schema variants for elicitation requests: titled/untitled single-select and titled/untitled multi-select. The TypeScript SDK ships typed Zod definitions for each shape (packages/core/src/types/schemas.ts), and the Python SDK relies on hand-built schemas with the same shapes in its conformance fixtures.

Adds builder class methods on MCP::Elicitation::EnumSchema that produce the canonical JSON-Schema shapes for each variant, plus a legacy_titled builder retained for backward compatibility with clients that have not yet migrated. Each constructor returns an EnumSchema instance whose to_h produces the property-value Hash to pass through requested_schema: on ServerSession#create_form_elicitation.

Each builder maps one-to-one to the spec's schema type names in schema/2025-11-25/schema.ts, which the TypeScript and Python SDKs also carry verbatim in their type layers:

Spec type (schema.ts) Builder
UntitledSingleSelectEnumSchema untitled_single_select
TitledSingleSelectEnumSchema titled_single_select
UntitledMultiSelectEnumSchema untitled_multi_select
TitledMultiSelectEnumSchema titled_multi_select
LegacyTitledEnumSchema (deprecated in the spec) legacy_titled
EnumSchema (the union of all five) the MCP::Elicitation::EnumSchema class itself

These shapes stay relevant on the stateless 2026-07-28 lifecycle: elicitation is not deprecated by SEP-2577 and reaches modern clients as elicitation/create requests embedded in SEP-2322 input_required results, whose requestedSchema uses the same variants. The README documents that pairing; the example references MCP::Server::InputRequiredResult, so this change should merge after the SEP-2322 server-side PR.

The conformance server now builds the enum schemas of its test_elicitation_sep1330_enums tool (and the status enum of the SEP-1034 defaults tool) through these builders instead of hand-written hashes, so the conformance run exercises the exact schemas the SDK produces for users.

How Has This Been Tested?

test/mcp/elicitation/enum_schema_test.rb covers each of the five shapes with happy-path emission, default propagation, title / description propagation, and the four ArgumentError cases (empty values, missing :value, missing :title, mismatched value_titles length). Two additional regression tests assert that empty-but-non-nil defaults survive to_h:

  • EnumSchema.untitled_single_select(default: "") keeps the empty string in the emitted Hash
  • EnumSchema.untitled_multi_select(default: []) keeps the empty array in the emitted Hash

bundle exec rake (tests, RuboCop, and conformance baseline) passes; the elicitation-sep1330-enums and elicitation-sep1034-defaults conformance scenarios pass with the builder-produced schemas, confirming they emit the same wire shapes as the previous hand-written hashes.

Breaking Changes

None. The change is purely additive: new module MCP::Elicitation::EnumSchema with new class methods. Existing callers of ServerSession#create_form_elicitation that pass raw hashes continue to work unchanged.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

@koic koic changed the title Add MCP::Elicitation::EnumSchema builders for SEP-1330 Add MCP::Elicitation::EnumSchema builders for SEP-1330 Aug 5, 2026
## Motivation and Context

MCP 2025-11-25 (SEP-1330) replaces the ad-hoc `enumNames` convention with four standards-based enum schema variants
for elicitation requests: titled/untitled single-select and titled/untitled multi-select. The TypeScript SDK ships
typed Zod definitions for each shape (`packages/core/src/types/schemas.ts`), and the Python SDK relies on hand-built
schemas with the same shapes in its conformance fixtures.

Adds builder class methods on `MCP::Elicitation::EnumSchema` that produce the canonical JSON-Schema shapes for each variant,
plus a `legacy_titled` builder retained for backward compatibility with clients that have not yet migrated.
Each constructor returns an `EnumSchema` instance whose `to_h` produces the property-value Hash to pass through
`requested_schema:` on `ServerSession#create_form_elicitation`.

Each builder maps one-to-one to the spec's schema type names in `schema/2025-11-25/schema.ts`,
which the TypeScript and Python SDKs also carry verbatim in their type layers:

| Spec type (schema.ts)                             | Builder                                         |
|---------------------------------------------------|-------------------------------------------------|
| `UntitledSingleSelectEnumSchema`                  | `untitled_single_select`                        |
| `TitledSingleSelectEnumSchema`                    | `titled_single_select`                          |
| `UntitledMultiSelectEnumSchema`                   | `untitled_multi_select`                         |
| `TitledMultiSelectEnumSchema`                     | `titled_multi_select`                           |
| `LegacyTitledEnumSchema` (deprecated in the spec) | `legacy_titled`                                 |
| `EnumSchema` (the union of all five)              | the `MCP::Elicitation::EnumSchema` class itself |

These shapes stay relevant on the stateless 2026-07-28 lifecycle: elicitation is not deprecated by SEP-2577
and reaches modern clients as `elicitation/create` requests embedded in SEP-2322 `input_required` results,
whose `requestedSchema` uses the same variants. The README documents that pairing; the example references
`MCP::Server::InputRequiredResult`, so this change should merge after the SEP-2322 server-side PR.

The conformance server now builds the enum schemas of its `test_elicitation_sep1330_enums` tool
(and the `status` enum of the SEP-1034 defaults tool) through these builders instead of hand-written hashes,
so the conformance run exercises the exact schemas the SDK produces for users.

## How Has This Been Tested?

`test/mcp/elicitation/enum_schema_test.rb` covers each of the five shapes with happy-path emission,
`default` propagation, `title` / `description` propagation, and the four ArgumentError cases
(empty values, missing `:value`, missing `:title`, mismatched `value_titles` length). Two additional regression tests
assert that empty-but-non-nil defaults survive `to_h`:

- `EnumSchema.untitled_single_select(default: "")` keeps the empty string in the emitted Hash
- `EnumSchema.untitled_multi_select(default: [])` keeps the empty array in the emitted Hash

`bundle exec rake` (tests, RuboCop, and conformance baseline) passes; the `elicitation-sep1330-enums`
and `elicitation-sep1034-defaults` conformance scenarios pass with the builder-produced schemas,
confirming they emit the same wire shapes as the previous hand-written hashes.

## Breaking Changes

None. The change is purely additive: new module `MCP::Elicitation::EnumSchema` with new class methods.
Existing callers of `ServerSession#create_form_elicitation` that pass raw hashes continue to work unchanged.
@koic
koic force-pushed the elicitation_enum_schema branch from d2a8065 to b54eeba Compare August 5, 2026 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant