ruby-sdk/lib/mcp/elicitation
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO b54eebac75 Add MCP::Elicitation::EnumSchema builders for SEP-1330
## 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.
2026-08-05 12:26:13 +09:00
..
enum_schema.rb Add MCP::Elicitation::EnumSchema builders for SEP-1330 2026-08-05 12:26:13 +09:00