Skip to content

We need basic "cancel / reject / accept" elicitations requiring only confirmation / reject with no data #1284

@owengo

Description

@owengo

Initial Checks

Description

It would be nice to create very simple cancel / reject / accept elicitations like this:

# Elicitation schemas for user confirmation
class CreateDocumentConfirmation(BaseModel):
    """Schema for create document confirmation."""
    #confirm: bool   <== We don't need this, it creates  a useless box to  the click for the client

An easy fix in elicitation.py would be:

    if result.action == "accept" and result.content:
        # Validate and parse the content using the schema
        validated_data = schema.model_validate(result.content)
        return AcceptedElicitation(data=validated_data)
    elif result.action == "accept":
        validated_data = schema.model_validate({})
        return AcceptedElicitation(data=validated_data)
    elif result.action == "decline":
        return DeclinedElicitation()
    elif result.action == "cancel":
        return CancelledElicitation()
    else:
        # This should never happen, but handle it just in case
        raise ValueError(f"Unexpected elicitation action: {result.action}")

Note that the typescript sdk allows this behavior:

The behavior is possible with the typescript sdk:

   const result = await server.server.elicitInput({
       message: `${confirmationMessage}`,
        requestedSchema: {
         type: "object",
         properties: {
         },
         required: []
       }
     });  
     if (result.action === "accept") { 
       log.warn(`User accepted usage of ${toolName}`, {
         user: userEmail,
       });
       return true;
     } else {
...

Example Code

from mcp.server.fastmcp import Context, FastMCP

# Elicitation schemas for user confirmation
class CreateDocumentConfirmation(BaseModel):
    """Schema for create document confirmation."""

mcp = FastMCP("test-elicit")

@mcp.tool()
async def create_document(
    ctx: Context[ServerSession, None],
    name: str,
    html_content: str
) -> Dict[str, Any]:
    """Create a new  document"""
    user_email = await check_user_auth(ctx)
    start_time = time.time()
    
    try:
        # Request user confirmation via elicitation
        try:
            await ctx.info(f"Requesting confirmation for document creation: {name}")
            confirmation_result = await ctx.elicit(
                f"Are you sure you want to create document '{name}'?",
                CreateDocumentConfirmation
            )
            
            await ctx.info(f"Confirmation result: {confirmation_result.action}")
            if confirmation_result.action != "accept":
                return {"result": f"Document creation cancelled by user"}
                
        except Exception as elicit_error:
            await ctx.error(f"Elicitation failed: {elicit_error}")
            return {"result": f"Document creation cancelled due to confirmation error"}
 ...


So currently this example *does not work* because of the validation issue , we have a: ValueError(f"Unexpected elicitation action: {result.action}")  ( where result.action == "accept" ) .

Python & MCP Python SDK

python3.11
mcp-1.13.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions