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
Reactions are currently unavailable
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 clientAn 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
Python & MCP Python SDK