fast-agent-mcp 0.2.36__tar.gz → 0.2.37__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/.gitignore +4 -1
  2. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/LICENSE +1 -1
  3. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/PKG-INFO +10 -7
  4. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/README.md +3 -1
  5. fast_agent_mcp-0.2.37/examples/mcp/elicitations/README.md +157 -0
  6. fast_agent_mcp-0.2.37/examples/mcp/elicitations/elicitation_account_server.py +88 -0
  7. fast_agent_mcp-0.2.37/examples/mcp/elicitations/elicitation_forms_server.py +232 -0
  8. fast_agent_mcp-0.2.37/examples/mcp/elicitations/elicitation_game_server.py +164 -0
  9. fast_agent_mcp-0.2.37/examples/mcp/elicitations/fastagent.config.yaml +35 -0
  10. fast_agent_mcp-0.2.37/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
  11. fast_agent_mcp-0.2.37/examples/mcp/elicitations/forms_demo.py +111 -0
  12. fast_agent_mcp-0.2.37/examples/mcp/elicitations/game_character.py +65 -0
  13. fast_agent_mcp-0.2.37/examples/mcp/elicitations/game_character_handler.py +256 -0
  14. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/agent.py → fast_agent_mcp-0.2.37/examples/mcp/elicitations/tool_call.py +4 -5
  15. {fast_agent_mcp-0.2.36/src/mcp_agent/resources → fast_agent_mcp-0.2.37}/examples/mcp/state-transfer/fastagent.config.yaml +1 -1
  16. {fast_agent_mcp-0.2.36/src/mcp_agent/resources → fast_agent_mcp-0.2.37}/examples/mcp/state-transfer/fastagent.secrets.yaml.example +1 -0
  17. fast_agent_mcp-0.2.37/examples/mcp/vision-examples/cat.png +0 -0
  18. fast_agent_mcp-0.2.37/examples/tensorzero/.env.sample +2 -0
  19. fast_agent_mcp-0.2.37/examples/tensorzero/Makefile +31 -0
  20. fast_agent_mcp-0.2.37/examples/tensorzero/demo_images/clam.jpg +0 -0
  21. fast_agent_mcp-0.2.37/examples/tensorzero/demo_images/crab.png +0 -0
  22. fast_agent_mcp-0.2.37/examples/tensorzero/demo_images/shrimp.png +0 -0
  23. fast_agent_mcp-0.2.37/examples/tensorzero/mcp_server/Dockerfile +28 -0
  24. fast_agent_mcp-0.2.37/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
  25. fast_agent_mcp-0.2.37/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
  26. fast_agent_mcp-0.2.37/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
  27. fast_agent_mcp-0.2.37/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
  28. fast_agent_mcp-0.2.37/hatch_build.py +66 -0
  29. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/pyproject.toml +15 -25
  30. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/commands/quickstart.py +59 -5
  31. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/config.py +10 -0
  32. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/context.py +1 -4
  33. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/agent_types.py +7 -6
  34. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/direct_decorators.py +14 -0
  35. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/direct_factory.py +1 -0
  36. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/fastagent.py +23 -2
  37. fast_agent_mcp-0.2.37/src/mcp_agent/human_input/elicitation_form.py +723 -0
  38. fast_agent_mcp-0.2.37/src/mcp_agent/human_input/elicitation_forms.py +59 -0
  39. fast_agent_mcp-0.2.37/src/mcp_agent/human_input/elicitation_handler.py +88 -0
  40. fast_agent_mcp-0.2.37/src/mcp_agent/human_input/elicitation_state.py +34 -0
  41. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_google_native.py +4 -2
  42. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_openai.py +1 -1
  43. fast_agent_mcp-0.2.37/src/mcp_agent/mcp/elicitation_factory.py +84 -0
  44. fast_agent_mcp-0.2.37/src/mcp_agent/mcp/elicitation_handlers.py +155 -0
  45. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/helpers/content_helpers.py +27 -0
  46. fast_agent_mcp-0.2.37/src/mcp_agent/mcp/helpers/server_config_helpers.py +25 -0
  47. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/mcp_agent_client_session.py +44 -1
  48. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/mcp_aggregator.py +56 -11
  49. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/mcp_connection_manager.py +30 -18
  50. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp_server/agent_server.py +2 -0
  51. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp_server_registry.py +16 -8
  52. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/data-analysis/analysis.py +1 -2
  53. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/README.md +157 -0
  54. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
  55. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +232 -0
  56. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
  57. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
  58. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
  59. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/forms_demo.py +111 -0
  60. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
  61. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
  62. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
  63. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +1 -1
  64. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37/src/mcp_agent/resources}/examples/mcp/state-transfer/fastagent.config.yaml +2 -2
  65. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
  66. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/evaluator.py +1 -1
  67. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/workflows/graded_report.md +89 -0
  68. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/orchestrator.py +7 -9
  69. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -2
  70. fast_agent_mcp-0.2.37/src/mcp_agent/resources/examples/workflows/short_story.md +13 -0
  71. fast_agent_mcp-0.2.36/src/mcp_agent/mcp/helpers/server_config_helpers.py +0 -23
  72. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -84
  73. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -21
  74. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/slides.py +0 -110
  75. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/agent.py +0 -20
  76. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -66
  77. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -35
  78. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/job.py +0 -84
  79. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -21
  80. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -51
  81. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/simple.txt +0 -2
  82. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/sizer.py +0 -20
  83. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/social.py +0 -67
  84. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/__init__.py +0 -3
  85. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -14
  86. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -43
  87. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/image_server.py +0 -52
  88. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -6
  89. fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -19
  90. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/azure-openai/fastagent.config.yaml +0 -0
  91. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/custom-agents/agent.py +0 -0
  92. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/custom-agents/fastagent.config.yaml +0 -0
  93. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/data-analysis/analysis-campaign.py +0 -0
  94. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/data-analysis/analysis.py +0 -0
  95. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/data-analysis/fastagent.config.yaml +0 -0
  96. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  97. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/state-transfer/agent_one.py +0 -0
  98. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/state-transfer/agent_two.py +0 -0
  99. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/vision-examples/example1.py +0 -0
  100. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/vision-examples/example2.py +0 -0
  101. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/vision-examples/example3.py +0 -0
  102. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
  103. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/otel/agent.py +0 -0
  104. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/otel/agent2.py +0 -0
  105. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/otel/docker-compose.yaml +0 -0
  106. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/otel/fastagent.config.yaml +0 -0
  107. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/researcher/fastagent.config.yaml +0 -0
  108. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/researcher/researcher-eval.py +0 -0
  109. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/researcher/researcher-imp.py +0 -0
  110. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/researcher/researcher.py +0 -0
  111. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/README.md +0 -0
  112. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/agent.py +0 -0
  113. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/docker-compose.yml +0 -0
  114. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/fastagent.config.yaml +0 -0
  115. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/image_demo.py +0 -0
  116. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/mcp_server/mcp_server.py +0 -0
  117. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/tensorzero/simple_agent.py +0 -0
  118. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/chaining.py +0 -0
  119. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/evaluator.py +0 -0
  120. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/fastagent.config.yaml +0 -0
  121. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/graded_report.md +0 -0
  122. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/human_input.py +0 -0
  123. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/orchestrator.py +0 -0
  124. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/parallel.py +0 -0
  125. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/router.py +0 -0
  126. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/short_story.md +0 -0
  127. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/examples/workflows/short_story.txt +0 -0
  128. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/__init__.py +0 -0
  129. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/__init__.py +0 -0
  130. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/agent.py +0 -0
  131. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/base_agent.py +0 -0
  132. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/__init__.py +0 -0
  133. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
  134. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
  135. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
  136. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
  137. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
  138. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
  139. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/agents/workflow/router_agent.py +0 -0
  140. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/app.py +0 -0
  141. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/__init__.py +0 -0
  142. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/__main__.py +0 -0
  143. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/commands/check_config.py +0 -0
  144. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/commands/go.py +0 -0
  145. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/commands/setup.py +0 -0
  146. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/commands/url_parser.py +0 -0
  147. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/main.py +0 -0
  148. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/cli/terminal.py +0 -0
  149. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/console.py +0 -0
  150. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/context_dependent.py +0 -0
  151. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/__init__.py +0 -0
  152. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/agent_app.py +0 -0
  153. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/enhanced_prompt.py +0 -0
  154. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/error_handling.py +0 -0
  155. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/exceptions.py +0 -0
  156. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/interactive_prompt.py +0 -0
  157. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/mcp_content.py +0 -0
  158. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/prompt.py +0 -0
  159. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/request_params.py +0 -0
  160. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/usage_display.py +0 -0
  161. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/core/validation.py +0 -0
  162. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/event_progress.py +0 -0
  163. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/executor/__init__.py +0 -0
  164. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/executor/executor.py +0 -0
  165. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/executor/task_registry.py +0 -0
  166. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/executor/workflow_signal.py +0 -0
  167. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/human_input/__init__.py +0 -0
  168. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/human_input/handler.py +0 -0
  169. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/human_input/types.py +0 -0
  170. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/__init__.py +0 -0
  171. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/augmented_llm.py +0 -0
  172. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
  173. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
  174. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/augmented_llm_slow.py +0 -0
  175. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/memory.py +0 -0
  176. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/model_database.py +0 -0
  177. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/model_factory.py +0 -0
  178. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/prompt_utils.py +0 -0
  179. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/provider_key_manager.py +0 -0
  180. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/provider_types.py +0 -0
  181. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/__init__.py +0 -0
  182. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
  183. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_aliyun.py +0 -0
  184. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +0 -0
  185. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_azure.py +0 -0
  186. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
  187. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
  188. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_google_oai.py +0 -0
  189. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
  190. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/augmented_llm_tensorzero.py +0 -0
  191. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/google_converter.py +0 -0
  192. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
  193. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
  194. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/multipart_converter_tensorzero.py +0 -0
  195. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
  196. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
  197. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
  198. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
  199. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/sampling_converter.py +0 -0
  200. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
  201. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/llm/usage_tracking.py +0 -0
  202. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/__init__.py +0 -0
  203. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/events.py +0 -0
  204. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/json_serializer.py +0 -0
  205. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/listeners.py +0 -0
  206. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/logger.py +0 -0
  207. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/rich_progress.py +0 -0
  208. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/logging/transport.py +0 -0
  209. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/__init__.py +0 -0
  210. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/common.py +0 -0
  211. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/gen_client.py +0 -0
  212. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
  213. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/hf_auth.py +0 -0
  214. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/interfaces.py +0 -0
  215. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/logger_textio.py +0 -0
  216. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/mime_utils.py +0 -0
  217. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
  218. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompt_render.py +0 -0
  219. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
  220. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  221. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  222. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
  223. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
  224. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
  225. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
  226. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
  227. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/resource_utils.py +0 -0
  228. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp/sampling.py +0 -0
  229. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/mcp_server/__init__.py +0 -0
  230. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/progress_display.py +0 -0
  231. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
  232. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  233. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  234. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
  235. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  236. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  237. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
  238. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  239. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  240. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  241. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  242. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  243. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
  244. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/tools/tool_definition.py +0 -0
  245. {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.37}/src/mcp_agent/ui/console_display.py +0 -0
@@ -85,7 +85,7 @@ ipython_config.py
85
85
  # pyenv
86
86
  # For a library or package, you might want to ignore these files since the code is
87
87
  # intended to run in multiple environments; otherwise, check them in:
88
- # .python-version
88
+ .python-version
89
89
 
90
90
  # pipenv
91
91
  # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -160,6 +160,9 @@ examples/**/*.secrets.yaml
160
160
  # but make sure example files are
161
161
  !examples/**/*.secrets.yaml.example
162
162
 
163
+ # Build-generated resources (copied from examples/ during build)
164
+ src/mcp_agent/resources/examples/
165
+
163
166
  # Test data files
164
167
  examples/mcp_root_test/test_data/*.png
165
168
 
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [2025] [llmindset.co.uk]
189
+ Copyright 2025 llmindset.co.uk
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.36
3
+ Version: 0.2.37
4
4
  Summary: Define, Prompt and Test MCP enabled Agents and Workflows
5
5
  Author-email: Shaun Smith <fastagent@llmindset.co.uk>
6
6
  License: Apache License
@@ -191,7 +191,7 @@ License: Apache License
191
191
  same "printed page" as the copyright notice for easier
192
192
  identification within third-party archives.
193
193
 
194
- Copyright [2025] [llmindset.co.uk]
194
+ Copyright 2025 llmindset.co.uk
195
195
 
196
196
  Licensed under the Apache License, Version 2.0 (the "License");
197
197
  you may not use this file except in compliance with the License.
@@ -208,22 +208,23 @@ License-File: LICENSE
208
208
  Classifier: License :: OSI Approved :: Apache Software License
209
209
  Classifier: Operating System :: OS Independent
210
210
  Classifier: Programming Language :: Python :: 3
211
- Requires-Python: >=3.10
211
+ Requires-Python: >=3.12
212
212
  Requires-Dist: a2a-sdk>=0.2.9
213
213
  Requires-Dist: aiohttp>=3.11.13
214
214
  Requires-Dist: anthropic>=0.55.0
215
215
  Requires-Dist: azure-identity>=1.14.0
216
216
  Requires-Dist: deprecated>=1.2.18
217
+ Requires-Dist: email-validator>=2.2.0
217
218
  Requires-Dist: fastapi>=0.115.6
218
219
  Requires-Dist: google-genai
219
220
  Requires-Dist: mcp==1.10.1
220
221
  Requires-Dist: openai>=1.93.0
221
222
  Requires-Dist: opentelemetry-distro>=0.50b0
222
223
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
223
- Requires-Dist: opentelemetry-instrumentation-anthropic>=0.40.7; python_version >= '3.10' and python_version < '4.0'
224
+ Requires-Dist: opentelemetry-instrumentation-anthropic>=0.40.14; python_version >= '3.10' and python_version < '4.0'
224
225
  Requires-Dist: opentelemetry-instrumentation-google-genai>=0.2b0
225
- Requires-Dist: opentelemetry-instrumentation-mcp>=0.40.7; python_version >= '3.10' and python_version < '4.0'
226
- Requires-Dist: opentelemetry-instrumentation-openai>=0.0.40.7; python_version >= '3.10' and python_version < '4.0'
226
+ Requires-Dist: opentelemetry-instrumentation-mcp>=0.40.14; python_version >= '3.10' and python_version < '4.0'
227
+ Requires-Dist: opentelemetry-instrumentation-openai>=0.40.14; python_version >= '3.10' and python_version < '4.0'
227
228
  Requires-Dist: prompt-toolkit>=3.0.50
228
229
  Requires-Dist: pydantic-settings>=2.7.0
229
230
  Requires-Dist: pydantic>=2.10.4
@@ -261,7 +262,9 @@ Description-Content-Type: text/markdown
261
262
  > [!TIP]
262
263
  > Documentation site is in production here : https://fast-agent.ai. Feel free to feed back what's helpful and what's not. There is also an LLMs.txt [here](https://fast-agent.ai/llms.txt)
263
264
 
264
- **`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o/gpt-4.1 family, o1/o3 family) are supported.
265
+ **`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Model support is comprehensive with native support for Anthropic, OpenAI and Google as well as Azure, Ollama, Deepseek and dozens of others via TensorZero.
266
+
267
+ ![multi_model_trim](https://github.com/user-attachments/assets/c8bf7474-2c41-4ef3-8924-06e29907d7c6)
265
268
 
266
269
  The simple declarative syntax lets you concentrate on composing your Prompts and MCP Servers to [build effective agents](https://www.anthropic.com/research/building-effective-agents).
267
270
 
@@ -12,7 +12,9 @@
12
12
  > [!TIP]
13
13
  > Documentation site is in production here : https://fast-agent.ai. Feel free to feed back what's helpful and what's not. There is also an LLMs.txt [here](https://fast-agent.ai/llms.txt)
14
14
 
15
- **`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o/gpt-4.1 family, o1/o3 family) are supported.
15
+ **`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Model support is comprehensive with native support for Anthropic, OpenAI and Google as well as Azure, Ollama, Deepseek and dozens of others via TensorZero.
16
+
17
+ ![multi_model_trim](https://github.com/user-attachments/assets/c8bf7474-2c41-4ef3-8924-06e29907d7c6)
16
18
 
17
19
  The simple declarative syntax lets you concentrate on composing your Prompts and MCP Servers to [build effective agents](https://www.anthropic.com/research/building-effective-agents).
18
20
 
@@ -0,0 +1,157 @@
1
+ # Quick Start: MCP Elicitations
2
+
3
+ This quickstart demonstrates **fast-agent**'s elicitation feature - a powerful way to collect structured data from users through forms and interactive prompts.
4
+
5
+ ## What are Elicitations?
6
+
7
+ Elicitations allow MCP servers to request structured input from users through type-safe forms. This enables:
8
+ - User preference collection
9
+ - Account registration flows
10
+ - Configuration wizards
11
+ - Interactive feedback forms
12
+ - Any scenario requiring structured user input
13
+
14
+ ## Examples Included
15
+
16
+ ### 1. Forms Demo (`forms_demo.py`)
17
+ A showcase of different form types with beautiful rich console output. Uses the passthrough model to display forms directly to users.
18
+
19
+ ```bash
20
+ uv run forms_demo.py
21
+ ```
22
+
23
+ This example demonstrates:
24
+ - User profile collection
25
+ - Preference settings
26
+ - Simple yes/no ratings
27
+ - Detailed feedback forms
28
+
29
+ ### 2. Account Creation Assistant (`account_creation.py`)
30
+ An AI-powered account creation workflow where the LLM initiates the account signup process and the user fills out the form.
31
+
32
+ ```bash
33
+ # Configure your LLM first (edit fastagent.config.yaml)
34
+ uv run account_creation.py --model gpt-4o
35
+ ```
36
+
37
+ This example shows:
38
+ - LLM initiating elicitation via tool calls
39
+ - User filling out the form (not the LLM)
40
+ - Tool call errors when user cancels/declines
41
+ - Success handling when form is completed
42
+
43
+ ### 3. Game Character Creator (`game_character.py` + `game_character_handler.py`)
44
+ A whimsical example with custom elicitation handling, featuring animated dice rolls and visual effects.
45
+
46
+ ```bash
47
+ uv run game_character.py
48
+ ```
49
+
50
+ Features:
51
+ - Custom elicitation handler (in separate module for clarity)
52
+ - Animated progress bars and typewriter effects
53
+ - Epic dice roll mechanics with cosmic bonuses
54
+ - Interactive character creation with theatrical flair
55
+ - Demonstrates proper handler file organization
56
+
57
+ ## Getting Started
58
+
59
+ 1. **Setup your environment:**
60
+ ```bash
61
+ # Activate your Python environment
62
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
63
+
64
+ # Install dependencies if needed
65
+ uv pip install fast-agent-mcp
66
+ ```
67
+
68
+ 2. **For the account creation example**, rename `fastagent.secrets.yaml.example` to `fastagent.secrets.yaml` and add your API keys.
69
+
70
+ 3. **Run an example:**
71
+ ```bash
72
+ # Try the forms demo first (quiet mode enabled programmatically)
73
+ uv run forms_demo.py
74
+ ```
75
+
76
+ ## How Elicitations Work
77
+
78
+ ### Elicitation Modes
79
+
80
+ **fast-agent** supports these elicitation modes:
81
+
82
+ 1. **`forms`** - Shows forms to users (great with passthrough model)
83
+ 2. **`auto_cancel`** - Automatically cancels all elicitations
84
+ 3. **`none`** - No elicitation handling
85
+ 4. **Custom handler** - Use your own handler function (overrides mode setting)
86
+
87
+ Configure modes in `fastagent.config.yaml`:
88
+
89
+ ```yaml
90
+ mcp:
91
+ servers:
92
+ my_server:
93
+ command: "uv"
94
+ args: ["run", "server.py"]
95
+ elicitation:
96
+ mode: "forms" # or "auto" or "custom"
97
+ ```
98
+
99
+ ### Creating Your Own Elicitations
100
+
101
+ #### Basic Server-Side Elicitation
102
+
103
+ ```python
104
+ from pydantic import BaseModel, Field
105
+
106
+ class UserPrefs(BaseModel):
107
+ theme: str = Field(
108
+ description="Color theme",
109
+ json_schema_extra={
110
+ "enum": ["light", "dark"],
111
+ "enumNames": ["Light Mode", "Dark Mode"]
112
+ }
113
+ )
114
+ notifications: bool = Field(True, description="Enable notifications?")
115
+
116
+ # In your MCP server:
117
+ result = await mcp.get_context().elicit(
118
+ "Configure your preferences",
119
+ schema=UserPrefs
120
+ )
121
+ ```
122
+
123
+ #### Custom Elicitation Handler
124
+
125
+ For advanced interactive experiences, create a custom handler:
126
+
127
+ ```python
128
+ async def my_custom_handler(context, params) -> ElicitResult:
129
+ # Your custom logic here - animations, special effects, etc.
130
+ content = {"field": "value"}
131
+ return ElicitResult(action="accept", content=content)
132
+
133
+ # Register with your agent:
134
+ @fast.agent(
135
+ "my-agent",
136
+ servers=["my_server"],
137
+ elicitation_handler=my_custom_handler
138
+ )
139
+ ```
140
+
141
+ See `game_character_handler.py` for a complete example with animations and effects.
142
+
143
+ ## Next Steps
144
+
145
+ - Explore the example code to understand different patterns
146
+ - Try modifying the forms in `elicitation_server.py`
147
+ - Create your own custom elicitation handlers
148
+ - Check the [documentation](https://fast-agent.ai) for advanced features
149
+
150
+ ## Tips
151
+
152
+ - Use `rich` for beautiful console output
153
+ - Test with passthrough model first, then try real LLMs
154
+ - Custom handlers enable creative interactions
155
+ - Validate user input in your schemas using Pydantic
156
+
157
+ Happy form building! 🚀
@@ -0,0 +1,88 @@
1
+ """
2
+ MCP Server for Account Creation Demo
3
+
4
+ This server provides an account signup form that can be triggered
5
+ by tools, demonstrating LLM-initiated elicitations.
6
+
7
+ Note: Following MCP spec, we don't collect sensitive information like passwords.
8
+ """
9
+
10
+ import logging
11
+ import sys
12
+
13
+ from mcp.server.elicitation import (
14
+ AcceptedElicitation,
15
+ CancelledElicitation,
16
+ DeclinedElicitation,
17
+ )
18
+ from mcp.server.fastmcp import FastMCP
19
+ from pydantic import BaseModel, Field
20
+
21
+ # Configure logging
22
+ logging.basicConfig(
23
+ level=logging.INFO,
24
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
25
+ stream=sys.stderr,
26
+ )
27
+ logger = logging.getLogger("elicitation_account_server")
28
+
29
+ # Create MCP server
30
+ mcp = FastMCP("Account Creation Server", log_level="INFO")
31
+
32
+
33
+ @mcp.tool()
34
+ async def create_user_account(service_name: str = "MyApp") -> str:
35
+ """
36
+ Create a new user account for the specified service.
37
+
38
+ Args:
39
+ service_name: The name of the service to create an account for
40
+
41
+ Returns:
42
+ Status message about the account creation
43
+ """
44
+ # This tool triggers the elicitation form
45
+ logger.info(f"Creating account for service: {service_name}")
46
+
47
+ class AccountSignup(BaseModel):
48
+ username: str = Field(description="Choose a username", min_length=3, max_length=20)
49
+ email: str = Field(description="Your email address", json_schema_extra={"format": "email"})
50
+ full_name: str = Field(description="Your full name", max_length=30)
51
+
52
+ language: str = Field(
53
+ default="en",
54
+ description="Preferred language",
55
+ json_schema_extra={
56
+ "enum": [
57
+ "en",
58
+ "zh",
59
+ "es",
60
+ "fr",
61
+ "de",
62
+ "ja",
63
+ ],
64
+ "enumNames": ["English", "中文", "Español", "Français", "Deutsch", "日本語"],
65
+ },
66
+ )
67
+ agree_terms: bool = Field(description="I agree to the terms of service")
68
+ marketing_emails: bool = Field(False, description="Send me product updates")
69
+
70
+ result = await mcp.get_context().elicit(
71
+ f"Create Your {service_name} Account", schema=AccountSignup
72
+ )
73
+
74
+ match result:
75
+ case AcceptedElicitation(data=data):
76
+ if not data.agree_terms:
77
+ return "❌ Account creation failed: You must agree to the terms of service"
78
+ else:
79
+ return f"✅ Account created successfully for {service_name}!\nUsername: {data.username}\nEmail: {data.email}"
80
+ case DeclinedElicitation():
81
+ return f"❌ Account creation for {service_name} was declined by user"
82
+ case CancelledElicitation():
83
+ return f"❌ Account creation for {service_name} was cancelled by user"
84
+
85
+
86
+ if __name__ == "__main__":
87
+ logger.info("Starting account creation server...")
88
+ mcp.run()
@@ -0,0 +1,232 @@
1
+ """
2
+ MCP Server for Basic Elicitation Forms Demo
3
+
4
+ This server provides various elicitation resources that demonstrate
5
+ different form types and validation patterns.
6
+ """
7
+
8
+ import logging
9
+ import sys
10
+ from typing import Optional
11
+
12
+ from mcp import ReadResourceResult
13
+ from mcp.server.elicitation import (
14
+ AcceptedElicitation,
15
+ CancelledElicitation,
16
+ DeclinedElicitation,
17
+ )
18
+ from mcp.server.fastmcp import FastMCP
19
+ from mcp.types import TextResourceContents
20
+ from pydantic import AnyUrl, BaseModel, Field
21
+
22
+ # Configure logging
23
+ logging.basicConfig(
24
+ level=logging.INFO,
25
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
26
+ stream=sys.stderr,
27
+ )
28
+ logger = logging.getLogger("elicitation_forms_server")
29
+
30
+ # Create MCP server
31
+ mcp = FastMCP("Elicitation Forms Demo Server", log_level="INFO")
32
+
33
+
34
+ @mcp.resource(uri="elicitation://event-registration")
35
+ async def event_registration() -> ReadResourceResult:
36
+ """Register for a tech conference event."""
37
+
38
+ class EventRegistration(BaseModel):
39
+ name: str = Field(description="Your full name", min_length=2, max_length=100)
40
+ email: str = Field(description="Your email address", json_schema_extra={"format": "email"})
41
+ company_website: Optional[str] = Field(
42
+ None, description="Your company website (optional)", json_schema_extra={"format": "uri"}
43
+ )
44
+ event_date: str = Field(
45
+ description="Which event date works for you?", json_schema_extra={"format": "date"}
46
+ )
47
+ dietary_requirements: Optional[str] = Field(
48
+ None, description="Any dietary requirements? (optional)", max_length=200
49
+ )
50
+
51
+ result = await mcp.get_context().elicit(
52
+ "Register for the fast-agent conference - fill out your details",
53
+ schema=EventRegistration,
54
+ )
55
+
56
+ match result:
57
+ case AcceptedElicitation(data=data):
58
+ lines = [
59
+ f"✅ Registration confirmed for {data.name}",
60
+ f"📧 Email: {data.email}",
61
+ f"🏢 Company: {data.company_website or 'Not provided'}",
62
+ f"📅 Event Date: {data.event_date}",
63
+ f"🍽️ Dietary Requirements: {data.dietary_requirements or 'None'}",
64
+ ]
65
+ response = "\n".join(lines)
66
+ case DeclinedElicitation():
67
+ response = "Registration declined - no ticket reserved"
68
+ case CancelledElicitation():
69
+ response = "Registration cancelled - please try again later"
70
+
71
+ return ReadResourceResult(
72
+ contents=[
73
+ TextResourceContents(
74
+ mimeType="text/plain", uri=AnyUrl("elicitation://event-registration"), text=response
75
+ )
76
+ ]
77
+ )
78
+
79
+
80
+ @mcp.resource(uri="elicitation://product-review")
81
+ async def product_review() -> ReadResourceResult:
82
+ """Submit a product review with rating and comments."""
83
+
84
+ class ProductReview(BaseModel):
85
+ rating: int = Field(description="Rate this product (1-5 stars)", ge=1, le=5)
86
+ satisfaction: float = Field(
87
+ description="Overall satisfaction score (0.0-10.0)", ge=0.0, le=10.0
88
+ )
89
+ category: str = Field(
90
+ description="What type of product is this?",
91
+ json_schema_extra={
92
+ "enum": ["electronics", "books", "clothing", "home", "sports"],
93
+ "enumNames": [
94
+ "Electronics",
95
+ "Books & Media",
96
+ "Clothing",
97
+ "Home & Garden",
98
+ "Sports & Outdoors",
99
+ ],
100
+ },
101
+ )
102
+ review_text: str = Field(
103
+ description="Tell us about your experience", min_length=10, max_length=1000
104
+ )
105
+
106
+ result = await mcp.get_context().elicit(
107
+ "Share your product review - Help others make informed decisions!", schema=ProductReview
108
+ )
109
+
110
+ match result:
111
+ case AcceptedElicitation(data=data):
112
+ stars = "⭐" * data.rating
113
+ lines = [
114
+ "🎯 Product Review Submitted!",
115
+ f"⭐ Rating: {stars} ({data.rating}/5)",
116
+ f"📊 Satisfaction: {data.satisfaction}/10.0",
117
+ f"📦 Category: {data.category.replace('_', ' ').title()}",
118
+ f"💬 Review: {data.review_text}",
119
+ ]
120
+ response = "\n".join(lines)
121
+ case DeclinedElicitation():
122
+ response = "Review declined - no feedback submitted"
123
+ case CancelledElicitation():
124
+ response = "Review cancelled - you can submit it later"
125
+
126
+ return ReadResourceResult(
127
+ contents=[
128
+ TextResourceContents(
129
+ mimeType="text/plain", uri=AnyUrl("elicitation://product-review"), text=response
130
+ )
131
+ ]
132
+ )
133
+
134
+
135
+ @mcp.resource(uri="elicitation://account-settings")
136
+ async def account_settings() -> ReadResourceResult:
137
+ """Configure your account settings and preferences."""
138
+
139
+ class AccountSettings(BaseModel):
140
+ email_notifications: bool = Field(True, description="Receive email notifications?")
141
+ marketing_emails: bool = Field(False, description="Subscribe to marketing emails?")
142
+ theme: str = Field(
143
+ description="Choose your preferred theme",
144
+ json_schema_extra={
145
+ "enum": ["light", "dark", "auto"],
146
+ "enumNames": ["Light Theme", "Dark Theme", "Auto (System)"],
147
+ },
148
+ )
149
+ privacy_public: bool = Field(False, description="Make your profile public?")
150
+ items_per_page: int = Field(description="Items to show per page (10-100)", ge=10, le=100)
151
+
152
+ result = await mcp.get_context().elicit("Update your account settings", schema=AccountSettings)
153
+
154
+ match result:
155
+ case AcceptedElicitation(data=data):
156
+ lines = [
157
+ "⚙️ Account Settings Updated!",
158
+ f"📧 Email notifications: {'On' if data.email_notifications else 'Off'}",
159
+ f"📬 Marketing emails: {'On' if data.marketing_emails else 'Off'}",
160
+ f"🎨 Theme: {data.theme.title()}",
161
+ f"👥 Public profile: {'Yes' if data.privacy_public else 'No'}",
162
+ f"📄 Items per page: {data.items_per_page}",
163
+ ]
164
+ response = "\n".join(lines)
165
+ case DeclinedElicitation():
166
+ response = "Settings unchanged - keeping current preferences"
167
+ case CancelledElicitation():
168
+ response = "Settings update cancelled"
169
+
170
+ return ReadResourceResult(
171
+ contents=[
172
+ TextResourceContents(
173
+ mimeType="text/plain", uri=AnyUrl("elicitation://account-settings"), text=response
174
+ )
175
+ ]
176
+ )
177
+
178
+
179
+ @mcp.resource(uri="elicitation://service-appointment")
180
+ async def service_appointment() -> ReadResourceResult:
181
+ """Schedule a car service appointment."""
182
+
183
+ class ServiceAppointment(BaseModel):
184
+ customer_name: str = Field(description="Your full name", min_length=2, max_length=50)
185
+ vehicle_type: str = Field(
186
+ description="What type of vehicle do you have?",
187
+ json_schema_extra={
188
+ "enum": ["sedan", "suv", "truck", "motorcycle", "other"],
189
+ "enumNames": ["Sedan", "SUV/Crossover", "Truck", "Motorcycle", "Other"],
190
+ },
191
+ )
192
+ needs_loaner: bool = Field(description="Do you need a loaner vehicle?")
193
+ appointment_time: str = Field(
194
+ description="Preferred appointment date and time",
195
+ json_schema_extra={"format": "date-time"},
196
+ )
197
+ priority_service: bool = Field(False, description="Is this an urgent repair?")
198
+
199
+ result = await mcp.get_context().elicit(
200
+ "Schedule your vehicle service appointment", schema=ServiceAppointment
201
+ )
202
+
203
+ match result:
204
+ case AcceptedElicitation(data=data):
205
+ lines = [
206
+ "🔧 Service Appointment Scheduled!",
207
+ f"👤 Customer: {data.customer_name}",
208
+ f"🚗 Vehicle: {data.vehicle_type.title()}",
209
+ f"🚙 Loaner needed: {'Yes' if data.needs_loaner else 'No'}",
210
+ f"📅 Appointment: {data.appointment_time}",
211
+ f"⚡ Priority service: {'Yes' if data.priority_service else 'No'}",
212
+ ]
213
+ response = "\n".join(lines)
214
+ case DeclinedElicitation():
215
+ response = "Appointment cancelled - call us when you're ready!"
216
+ case CancelledElicitation():
217
+ response = "Appointment scheduling cancelled"
218
+
219
+ return ReadResourceResult(
220
+ contents=[
221
+ TextResourceContents(
222
+ mimeType="text/plain",
223
+ uri=AnyUrl("elicitation://service-appointment"),
224
+ text=response,
225
+ )
226
+ ]
227
+ )
228
+
229
+
230
+ if __name__ == "__main__":
231
+ logger.info("Starting elicitation forms demo server...")
232
+ mcp.run()