Skip to content

Conversation

@vincent0426
Copy link

Add support for string Enum types in elicitation schemas

Related PR: modelcontextprotocol/inspector#902

Changes Made

  • Added StrEnum to _ELICITATION_PRIMITIVE_TYPES tuple
  • Enhanced _is_primitive_field() to detect string enum types using issubclass() checks

Motivation and Context

Per https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation#supported-schema-types, elicitation schemas support enum types.

Currently, python-sdk only supported basic primitive types (str, int, float, bool) in elicitation schemas, but did not recognize Enum types.

How Has This Been Tested?

  • Added test cases in test_elicitation_schema_validation() to verify enum schemas

  • Manual test with

from enum import Enum, StrEnum

from pydantic import BaseModel, Field

from mcp.server.fastmcp import Context, FastMCP
from mcp.server.session import ServerSession

mcp = FastMCP(name="Elicitation Example")


class FruitEnum(str, Enum):
    pear = "pear"
    apple = "apple"


class TestStrEnum(StrEnum):
    one = "1"
    two = "2"
    three = "3"


class BookingPreferences(BaseModel):
    """Schema for collecting user preferences."""

    checkAlternative: bool = Field(description="Would you like to check another date?")
    alternativeDate: str = Field(
        default="2024-12-26",
        description="Alternative date (YYYY-MM-DD)",
    )
    fruit: FruitEnum = FruitEnum.pear
    strenum: TestStrEnum = TestStrEnum.one


@mcp.tool()
async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerSession, None]) -> str:
    """Book a table with date availability check."""
    # Check if date is available
    if date == "2024-12-25":
        # Date unavailable - ask user for alternative
        result = await ctx.elicit(
            message=(f"No tables available for {party_size} on {date}. Would you like to try another date?"),
            schema=BookingPreferences,
        )
        print(result)
        if result.action == "accept" and result.data:
            if result.data.checkAlternative:
                return f"[SUCCESS] Booked for {result.data.alternativeDate}"
            return "[CANCELLED] No booking made"
        return "[CANCELLED] Booking cancelled"

    # Date available
    return f"[SUCCESS] Booked for {date} at {time}"


@mcp.tool()
async def get_uuid(ctx: Context[ServerSession, None]) -> str:
    """Get a unique identifier."""
    result = await ctx.elicit(
        message="Please enter a unique identifier",
        schema=InvalidFormatSchema,
    )
    if result.action == "accept" and result.data:
        return f"[SUCCESS] Unique identifier: {result.data.id}"
    return "[CANCELLED] No unique identifier provided"


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

Results

Screenshot 2025-11-01 at 10 36 00 PM Screenshot 2025-11-01 at 10 36 02 PM

Breaking Changes

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

Additional context

The documentation doesn't explicitly specify that enums must be string enums. Should we add that clarification since both the TypeScript and Rust SDKs only support string enums?

https://github.com/modelcontextprotocol/typescript-sdk/blob/783d53be1049041cc1f0a23c070c3400208a94ff/src/types.ts#L1221-L1229

https://github.com/modelcontextprotocol/rust-sdk/blob/04e0590652d029e2cdfadee6f4c7255280dfba0e/crates/rmcp/src/model/elicitation_schema.rs#L479-L481

@vincent0426 vincent0426 force-pushed the fix/elicitation-str-enum branch from a44e8b3 to 07bef73 Compare November 2, 2025 06:06
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