fast-agent-mcp 0.2.36__tar.gz → 0.2.38__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.
Potentially problematic release.
This version of fast-agent-mcp might be problematic. Click here for more details.
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/.gitignore +4 -1
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/LICENSE +1 -1
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/PKG-INFO +10 -7
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/README.md +3 -1
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/elicitation_forms_server.py +232 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/forms_demo.py +111 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/game_character.py +65 -0
- fast_agent_mcp-0.2.38/examples/mcp/elicitations/game_character_handler.py +256 -0
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/agent.py → fast_agent_mcp-0.2.38/examples/mcp/elicitations/tool_call.py +4 -5
- {fast_agent_mcp-0.2.36/src/mcp_agent/resources → fast_agent_mcp-0.2.38}/examples/mcp/state-transfer/fastagent.config.yaml +1 -1
- {fast_agent_mcp-0.2.36/src/mcp_agent/resources → fast_agent_mcp-0.2.38}/examples/mcp/state-transfer/fastagent.secrets.yaml.example +1 -0
- fast_agent_mcp-0.2.38/examples/mcp/vision-examples/cat.png +0 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/.env.sample +2 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/Makefile +31 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/demo_images/clam.jpg +0 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/demo_images/crab.png +0 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/demo_images/shrimp.png +0 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/mcp_server/Dockerfile +28 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
- fast_agent_mcp-0.2.38/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
- fast_agent_mcp-0.2.38/hatch_build.py +66 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/pyproject.toml +15 -25
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/commands/quickstart.py +60 -5
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/config.py +10 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/context.py +1 -4
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/agent_types.py +7 -6
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/direct_decorators.py +14 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/direct_factory.py +1 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/fastagent.py +23 -2
- fast_agent_mcp-0.2.38/src/mcp_agent/human_input/elicitation_form.py +723 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/human_input/elicitation_forms.py +59 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/human_input/elicitation_handler.py +88 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/human_input/elicitation_state.py +34 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_google_native.py +4 -2
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_openai.py +1 -1
- fast_agent_mcp-0.2.38/src/mcp_agent/mcp/elicitation_factory.py +84 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/mcp/elicitation_handlers.py +155 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/helpers/content_helpers.py +27 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/mcp/helpers/server_config_helpers.py +25 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/mcp_agent_client_session.py +44 -1
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/mcp_aggregator.py +56 -11
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/mcp_connection_manager.py +30 -18
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp_server/agent_server.py +2 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp_server_registry.py +16 -8
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/data-analysis/analysis.py +1 -2
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +232 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/forms_demo.py +111 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +1 -1
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38/src/mcp_agent/resources}/examples/mcp/state-transfer/fastagent.config.yaml +2 -2
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/evaluator.py +1 -1
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/workflows/graded_report.md +89 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/orchestrator.py +7 -9
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -2
- fast_agent_mcp-0.2.38/src/mcp_agent/resources/examples/workflows/short_story.md +13 -0
- fast_agent_mcp-0.2.36/src/mcp_agent/mcp/helpers/server_config_helpers.py +0 -23
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -84
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -21
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/in_dev/slides.py +0 -110
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/agent.py +0 -20
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -66
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -35
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/job.py +0 -84
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -21
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -51
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/simple.txt +0 -2
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/sizer.py +0 -20
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/internal/social.py +0 -67
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/__init__.py +0 -3
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -14
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -43
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/image_server.py +0 -52
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -6
- fast_agent_mcp-0.2.36/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -19
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/azure-openai/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/custom-agents/agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/custom-agents/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/vision-examples/example1.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/vision-examples/example2.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/vision-examples/example3.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/otel/agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/otel/agent2.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/otel/docker-compose.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/otel/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/README.md +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/docker-compose.yml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/image_demo.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/tensorzero/simple_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/base_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/agents/workflow/router_agent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/app.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/__main__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/commands/check_config.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/commands/go.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/commands/setup.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/commands/url_parser.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/main.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/cli/terminal.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/console.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/context_dependent.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/agent_app.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/enhanced_prompt.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/error_handling.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/exceptions.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/interactive_prompt.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/mcp_content.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/prompt.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/request_params.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/usage_display.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/core/validation.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/event_progress.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/executor/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/executor/executor.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/executor/task_registry.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/executor/workflow_signal.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/human_input/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/human_input/handler.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/human_input/types.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/augmented_llm.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/augmented_llm_slow.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/memory.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/model_database.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/model_factory.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/prompt_utils.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/provider_key_manager.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/provider_types.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_aliyun.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_azure.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_google_oai.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/augmented_llm_tensorzero.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/google_converter.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/multipart_converter_tensorzero.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/sampling_converter.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/llm/usage_tracking.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/events.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/json_serializer.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/listeners.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/logger.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/rich_progress.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/logging/transport.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/common.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/gen_client.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/hf_auth.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/interfaces.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/logger_textio.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/mime_utils.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompt_render.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/resource_utils.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp/sampling.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/mcp_server/__init__.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/progress_display.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/src/mcp_agent/tools/tool_definition.py +0 -0
- {fast_agent_mcp-0.2.36 → fast_agent_mcp-0.2.38}/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
|
-
|
|
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
|
|
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.
|
|
3
|
+
Version: 0.2.38
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
226
|
-
Requires-Dist: opentelemetry-instrumentation-openai>=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.
|
|
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
|
+

|
|
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.
|
|
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
|
+

|
|
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,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()
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Server for Game Character Creation
|
|
3
|
+
|
|
4
|
+
This server provides a fun game character creation form
|
|
5
|
+
that can be used with custom handlers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import random
|
|
10
|
+
import sys
|
|
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_game_server")
|
|
29
|
+
|
|
30
|
+
# Create MCP server
|
|
31
|
+
mcp = FastMCP("Game Character Creation Server", log_level="INFO")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@mcp.resource(uri="elicitation://game-character")
|
|
35
|
+
async def game_character() -> ReadResourceResult:
|
|
36
|
+
"""Fun game character creation form for the whimsical example."""
|
|
37
|
+
|
|
38
|
+
class GameCharacter(BaseModel):
|
|
39
|
+
character_name: str = Field(description="Name your character", min_length=2, max_length=30)
|
|
40
|
+
character_class: str = Field(
|
|
41
|
+
description="Choose your class",
|
|
42
|
+
json_schema_extra={
|
|
43
|
+
"enum": ["warrior", "mage", "rogue", "ranger", "paladin", "bard"],
|
|
44
|
+
"enumNames": [
|
|
45
|
+
"⚔️ Warrior",
|
|
46
|
+
"🔮 Mage",
|
|
47
|
+
"🗡️ Rogue",
|
|
48
|
+
"🏹 Ranger",
|
|
49
|
+
"🛡️ Paladin",
|
|
50
|
+
"🎵 Bard",
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
)
|
|
54
|
+
strength: int = Field(description="Strength (3-18)", ge=3, le=18, default=10)
|
|
55
|
+
intelligence: int = Field(description="Intelligence (3-18)", ge=3, le=18, default=10)
|
|
56
|
+
dexterity: int = Field(description="Dexterity (3-18)", ge=3, le=18, default=10)
|
|
57
|
+
charisma: int = Field(description="Charisma (3-18)", ge=3, le=18, default=10)
|
|
58
|
+
lucky_dice: bool = Field(False, description="Roll for a lucky bonus?")
|
|
59
|
+
|
|
60
|
+
result = await mcp.get_context().elicit("🎮 Create Your Game Character!", schema=GameCharacter)
|
|
61
|
+
|
|
62
|
+
match result:
|
|
63
|
+
case AcceptedElicitation(data=data):
|
|
64
|
+
lines = [
|
|
65
|
+
f"🎭 Character Created: {data.character_name}",
|
|
66
|
+
f"Class: {data.character_class.title()}",
|
|
67
|
+
f"Stats: STR:{data.strength} INT:{data.intelligence} DEX:{data.dexterity} CHA:{data.charisma}",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
if data.lucky_dice:
|
|
71
|
+
dice_roll = random.randint(1, 20)
|
|
72
|
+
if dice_roll >= 15:
|
|
73
|
+
bonus = random.choice(
|
|
74
|
+
[
|
|
75
|
+
"🎁 Lucky! +2 to all stats!",
|
|
76
|
+
"🌟 Critical! Found a magic item!",
|
|
77
|
+
"💰 Jackpot! +100 gold!",
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
lines.append(f"🎲 Dice Roll: {dice_roll} - {bonus}")
|
|
81
|
+
else:
|
|
82
|
+
lines.append(f"🎲 Dice Roll: {dice_roll} - No bonus this time!")
|
|
83
|
+
|
|
84
|
+
total_stats = data.strength + data.intelligence + data.dexterity + data.charisma
|
|
85
|
+
if total_stats > 50:
|
|
86
|
+
lines.append("💪 Powerful character build!")
|
|
87
|
+
elif total_stats < 30:
|
|
88
|
+
lines.append("🎯 Challenging build - good luck!")
|
|
89
|
+
|
|
90
|
+
response = "\n".join(lines)
|
|
91
|
+
case DeclinedElicitation():
|
|
92
|
+
response = "Character creation declined - returning to menu"
|
|
93
|
+
case CancelledElicitation():
|
|
94
|
+
response = "Character creation cancelled"
|
|
95
|
+
|
|
96
|
+
return ReadResourceResult(
|
|
97
|
+
contents=[
|
|
98
|
+
TextResourceContents(
|
|
99
|
+
mimeType="text/plain", uri=AnyUrl("elicitation://game-character"), text=response
|
|
100
|
+
)
|
|
101
|
+
]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@mcp.tool()
|
|
106
|
+
async def roll_new_character(campaign_name: str = "Adventure") -> str:
|
|
107
|
+
"""
|
|
108
|
+
Roll a new character for your campaign.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
campaign_name: The name of the campaign
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Character details or status message
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
class GameCharacter(BaseModel):
|
|
118
|
+
character_name: str = Field(description="Name your character", min_length=2, max_length=30)
|
|
119
|
+
character_class: str = Field(
|
|
120
|
+
description="Choose your class",
|
|
121
|
+
json_schema_extra={
|
|
122
|
+
"enum": ["warrior", "mage", "rogue", "ranger", "paladin", "bard"],
|
|
123
|
+
"enumNames": [
|
|
124
|
+
"⚔️ Warrior",
|
|
125
|
+
"🔮 Mage",
|
|
126
|
+
"🗡️ Rogue",
|
|
127
|
+
"🏹 Ranger",
|
|
128
|
+
"🛡️ Paladin",
|
|
129
|
+
"🎵 Bard",
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
strength: int = Field(description="Strength (3-18)", ge=3, le=18, default=10)
|
|
134
|
+
intelligence: int = Field(description="Intelligence (3-18)", ge=3, le=18, default=10)
|
|
135
|
+
dexterity: int = Field(description="Dexterity (3-18)", ge=3, le=18, default=10)
|
|
136
|
+
charisma: int = Field(description="Charisma (3-18)", ge=3, le=18, default=10)
|
|
137
|
+
lucky_dice: bool = Field(False, description="Roll for a lucky bonus?")
|
|
138
|
+
|
|
139
|
+
result = await mcp.get_context().elicit(
|
|
140
|
+
f"🎮 Create Character for {campaign_name}!", schema=GameCharacter
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
match result:
|
|
144
|
+
case AcceptedElicitation(data=data):
|
|
145
|
+
response = f"🎭 {data.character_name} the {data.character_class.title()} joins {campaign_name}!\n"
|
|
146
|
+
response += f"Stats: STR:{data.strength} INT:{data.intelligence} DEX:{data.dexterity} CHA:{data.charisma}"
|
|
147
|
+
|
|
148
|
+
if data.lucky_dice:
|
|
149
|
+
dice_roll = random.randint(1, 20)
|
|
150
|
+
if dice_roll >= 15:
|
|
151
|
+
response += f"\n🎲 Lucky roll ({dice_roll})! Starting with bonus equipment!"
|
|
152
|
+
else:
|
|
153
|
+
response += f"\n🎲 Rolled {dice_roll} - Standard starting gear."
|
|
154
|
+
|
|
155
|
+
return response
|
|
156
|
+
case DeclinedElicitation():
|
|
157
|
+
return f"Character creation for {campaign_name} was declined"
|
|
158
|
+
case CancelledElicitation():
|
|
159
|
+
return f"Character creation for {campaign_name} was cancelled"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
logger.info("Starting game character creation server...")
|
|
164
|
+
mcp.run()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Model string takes format:
|
|
2
|
+
# <provider>.<model_string>.<reasoning_effort?> (e.g. anthropic.claude-3-5-sonnet-20241022 or openai.o3-mini.low)
|
|
3
|
+
#
|
|
4
|
+
# Can be overriden with a command line switch --model=<model>, or within the Agent decorator.
|
|
5
|
+
# Check here for current details: https://fast-agent.ai/models/
|
|
6
|
+
default_model: "passthrough"
|
|
7
|
+
|
|
8
|
+
# Logging and Console Configuration
|
|
9
|
+
logger:
|
|
10
|
+
level: "error"
|
|
11
|
+
type: "console"
|
|
12
|
+
|
|
13
|
+
# MCP Server Configuration
|
|
14
|
+
mcp:
|
|
15
|
+
servers:
|
|
16
|
+
# Forms demo server - interactive form examples
|
|
17
|
+
elicitation_forms_server:
|
|
18
|
+
command: "uv"
|
|
19
|
+
args: ["run", "elicitation_forms_server.py"]
|
|
20
|
+
elicitation:
|
|
21
|
+
mode: "forms" # Shows forms to users (default)
|
|
22
|
+
|
|
23
|
+
# Account creation server - for CALL_TOOL demos
|
|
24
|
+
elicitation_account_server:
|
|
25
|
+
command: "uv"
|
|
26
|
+
args: ["run", "elicitation_account_server.py"]
|
|
27
|
+
elicitation:
|
|
28
|
+
mode: "forms"
|
|
29
|
+
|
|
30
|
+
# Game character server - for custom handler demos
|
|
31
|
+
elicitation_game_server:
|
|
32
|
+
command: "uv"
|
|
33
|
+
args: ["run", "elicitation_game_server.py"]
|
|
34
|
+
elicitation:
|
|
35
|
+
mode: "forms"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Secrets configuration for elicitation examples
|
|
2
|
+
#
|
|
3
|
+
# Rename this file to fastagent.secrets.yaml and add your API keys
|
|
4
|
+
# to use the account_creation.py example with real LLMs
|
|
5
|
+
|
|
6
|
+
# OpenAI
|
|
7
|
+
openai_api_key: "sk-..."
|
|
8
|
+
|
|
9
|
+
# Anthropic
|
|
10
|
+
anthropic_api_key: "sk-ant-..."
|
|
11
|
+
|
|
12
|
+
# Google (Gemini)
|
|
13
|
+
google_api_key: "..."
|
|
14
|
+
|
|
15
|
+
# Other providers - see documentation for full list
|
|
16
|
+
# groq_api_key: "..."
|
|
17
|
+
# mistral_api_key: "..."
|