mcp_elicitation_example.py
1 #!/usr/bin/env python3 2 """ 3 MCP Elicitation Example 4 5 Demonstrates the Elicitation API per MCP 2025-11-25 specification. 6 Elicitation allows servers to request additional information from users. 7 8 Supports two modes: 9 - Form mode: Structured data collection with JSON schema validation 10 - URL mode: External URLs for sensitive interactions (OAuth, payments) 11 12 Usage: 13 python mcp_elicitation_example.py 14 """ 15 16 import asyncio 17 from praisonai.mcp_server.elicitation import ( 18 ElicitationHandler, 19 ElicitationResult, 20 create_form_request, 21 create_url_request, 22 ) 23 24 25 async def main(): 26 print("=" * 60) 27 print("MCP Elicitation Example (2025-11-25 Specification)") 28 print("=" * 60) 29 30 # Create handler in CI mode (non-interactive) with defaults 31 handler = ElicitationHandler( 32 ci_mode=True, 33 ci_defaults={ 34 "name": "John Doe", 35 "email": "john@example.com", 36 "confirm": True, 37 } 38 ) 39 40 # 1. Form mode elicitation 41 print("\n1. Form Mode Elicitation") 42 print("-" * 40) 43 44 form_request = create_form_request( 45 message="Please provide your contact information", 46 properties={ 47 "name": { 48 "type": "string", 49 "description": "Your full name", 50 }, 51 "email": { 52 "type": "string", 53 "format": "email", 54 "description": "Your email address", 55 }, 56 "age": { 57 "type": "integer", 58 "description": "Your age", 59 "default": 25, 60 }, 61 }, 62 required=["name", "email"], 63 title="Contact Form", 64 ) 65 66 print(f" Request message: {form_request.message}") 67 print(f" Request dict: {form_request.to_dict()}") 68 69 result = await handler.elicit(form_request) 70 print(f"\n Response action: {result.action.value}") 71 print(f" Response content: {result.content}") 72 print(f" MCP format: {result.to_dict()}") 73 74 # 2. URL mode elicitation 75 print("\n2. URL Mode Elicitation") 76 print("-" * 40) 77 78 url_request = create_url_request( 79 message="Please authorize access to your GitHub account", 80 url="https://github.com/login/oauth/authorize?client_id=xxx", 81 elicitation_id="oauth-github-123", 82 ) 83 84 print(f" Request message: {url_request.message}") 85 print(f" Request URL: {url_request.url}") 86 print(f" Elicitation ID: {url_request.elicitation_id}") 87 print(f" Request dict: {url_request.to_dict()}") 88 89 # URL mode returns decline in CI mode (cannot be automated) 90 result = await handler.elicit(url_request) 91 print(f"\n Response action: {result.action.value}") 92 print(" (URL mode cannot be completed in CI mode)") 93 94 # 3. Using factory methods 95 print("\n3. ElicitationResult Factory Methods") 96 print("-" * 40) 97 98 # Accept with data 99 accept_result = ElicitationResult.accept({"confirmed": True, "value": 42}) 100 print(f" Accept: {accept_result.to_dict()}") 101 102 # Decline with error 103 decline_result = ElicitationResult.decline("Invalid input provided") 104 print(f" Decline: {decline_result.to_dict()}") 105 106 # Cancel 107 cancel_result = ElicitationResult.cancel() 108 print(f" Cancel: {cancel_result.to_dict()}") 109 110 # 4. Custom handler 111 print("\n4. Custom Elicitation Handler") 112 print("-" * 40) 113 114 async def custom_handler(request): 115 """Custom handler that auto-approves everything.""" 116 print(f" Custom handler received: {request.message}") 117 return ElicitationResult.accept({"auto_approved": True}) 118 119 custom_elicit = ElicitationHandler() 120 custom_elicit.set_custom_handler(custom_handler) 121 122 test_request = create_form_request( 123 message="Test custom handler", 124 properties={"test": {"type": "string"}}, 125 ) 126 127 result = await custom_elicit.elicit(test_request) 128 print(f" Custom result: {result.to_dict()}") 129 130 print("\n" + "=" * 60) 131 print("Elicitation Example Complete!") 132 print("=" * 60) 133 134 135 if __name__ == "__main__": 136 asyncio.run(main())