fast-agent-mcp 0.2.19__tar.gz → 0.2.21__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.
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/PKG-INFO +2 -2
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/pyproject.toml +2 -2
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/__init__.py +1 -2
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/config.py +3 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/context.py +2 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/fastagent.py +5 -2
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm.py +35 -3
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +1 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_openai.py +1 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_agent_client_session.py +5 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_aggregator.py +103 -108
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_connection_manager.py +1 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_server.py +12 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server/agent_server.py +4 -1
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server_registry.py +1 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/.gitignore +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/LICENSE +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/README.md +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example1.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example2.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example3.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/agent2.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/docker-compose.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/base_agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/router_agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/app.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/__main__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/check_config.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/go.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/quickstart.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/setup.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/main.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/terminal.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/console.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/context_dependent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/agent_app.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/agent_types.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/direct_decorators.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/direct_factory.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/enhanced_prompt.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/error_handling.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/exceptions.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/interactive_prompt.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/mcp_content.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/prompt.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/request_params.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/validation.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/event_progress.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/executor.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/task_registry.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/workflow_signal.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/handler.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/types.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/memory.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/model_factory.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/prompt_utils.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/provider_key_manager.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/provider_types.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_google.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/sampling_converter.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/events.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/json_serializer.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/listeners.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/logger.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/rich_progress.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/transport.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/gen_client.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/interfaces.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/logger_textio.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mime_utils.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_render.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/resource_utils.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/sampling.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/progress_display.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/job.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/simple.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/social.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/agent.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/ui/console_display.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fast-agent-mcp
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.21
|
4
4
|
Summary: Define, Prompt and Test MCP enabled Agents and Workflows
|
5
5
|
Author-email: Shaun Smith <fastagent@llmindset.co.uk>, Sarmad Qadri <sarmad@lastmileai.dev>
|
6
6
|
License: Apache License
|
@@ -213,7 +213,7 @@ Requires-Dist: a2a-types>=0.1.0
|
|
213
213
|
Requires-Dist: aiohttp>=3.11.13
|
214
214
|
Requires-Dist: anthropic>=0.49.0
|
215
215
|
Requires-Dist: fastapi>=0.115.6
|
216
|
-
Requires-Dist: mcp
|
216
|
+
Requires-Dist: mcp~=1.7.0
|
217
217
|
Requires-Dist: openai>=1.63.2
|
218
218
|
Requires-Dist: opentelemetry-distro>=0.50b0
|
219
219
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "fast-agent-mcp"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.21"
|
4
4
|
description = "Define, Prompt and Test MCP enabled Agents and Workflows"
|
5
5
|
readme = "README.md"
|
6
6
|
license = { file = "LICENSE" }
|
@@ -16,7 +16,7 @@ classifiers = [
|
|
16
16
|
requires-python = ">=3.10"
|
17
17
|
dependencies = [
|
18
18
|
"fastapi>=0.115.6",
|
19
|
-
"mcp
|
19
|
+
"mcp~=1.7.0",
|
20
20
|
"opentelemetry-distro>=0.50b0",
|
21
21
|
"opentelemetry-exporter-otlp-proto-http>=1.29.0",
|
22
22
|
"pydantic-settings>=2.7.0",
|
@@ -36,7 +36,7 @@ from mcp_agent.core.request_params import RequestParams
|
|
36
36
|
|
37
37
|
# Core protocol interfaces
|
38
38
|
from mcp_agent.mcp.interfaces import AgentProtocol, AugmentedLLMProtocol
|
39
|
-
from mcp_agent.mcp.mcp_aggregator import MCPAggregator
|
39
|
+
from mcp_agent.mcp.mcp_aggregator import MCPAggregator
|
40
40
|
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
41
41
|
|
42
42
|
__all__ = [
|
@@ -58,7 +58,6 @@ __all__ = [
|
|
58
58
|
"Agent",
|
59
59
|
"AgentConfig",
|
60
60
|
"MCPAggregator",
|
61
|
-
"MCPCompoundServer",
|
62
61
|
"PromptMessageMultipart",
|
63
62
|
# FastAgent components
|
64
63
|
"FastAgent",
|
@@ -93,6 +93,9 @@ class MCPServerSettings(BaseModel):
|
|
93
93
|
sampling: MCPSamplingSettings | None = None
|
94
94
|
"""Sampling settings for this Client/Server pair"""
|
95
95
|
|
96
|
+
cwd: str | None = None
|
97
|
+
"""Working directory for the executed server command."""
|
98
|
+
|
96
99
|
|
97
100
|
class MCPSettings(BaseModel):
|
98
101
|
"""Configuration for all MCP servers."""
|
@@ -4,6 +4,7 @@ A central context object to store global state that is shared across the applica
|
|
4
4
|
|
5
5
|
import asyncio
|
6
6
|
import concurrent.futures
|
7
|
+
import uuid
|
7
8
|
from typing import TYPE_CHECKING, Any, Optional, Union
|
8
9
|
|
9
10
|
from mcp import ServerSession
|
@@ -79,12 +80,12 @@ async def configure_otel(config: "Settings") -> None:
|
|
79
80
|
except: # noqa: E722
|
80
81
|
app_version = "unknown"
|
81
82
|
|
82
|
-
# Create resource identifying this service
|
83
83
|
resource = Resource.create(
|
84
84
|
attributes={
|
85
85
|
key: value
|
86
86
|
for key, value in {
|
87
87
|
"service.name": service_name,
|
88
|
+
"service.instance.id": str(uuid.uuid4())[:6],
|
88
89
|
"service.version": app_version,
|
89
90
|
}.items()
|
90
91
|
if value is not None
|
@@ -324,13 +324,16 @@ class FastAgent:
|
|
324
324
|
print("\nServer stopped by user (Ctrl+C)")
|
325
325
|
except Exception as e:
|
326
326
|
if not quiet_mode:
|
327
|
+
import traceback
|
328
|
+
|
329
|
+
traceback.print_exc()
|
327
330
|
print(f"\nServer stopped with error: {e}")
|
328
331
|
|
329
332
|
# Exit after server shutdown
|
330
333
|
raise SystemExit(0)
|
331
334
|
|
332
335
|
# Handle direct message sending if --message is provided
|
333
|
-
if self.args.message:
|
336
|
+
if hasattr(self.args, "message") and self.args.message:
|
334
337
|
agent_name = self.args.agent
|
335
338
|
message = self.args.message
|
336
339
|
|
@@ -356,7 +359,7 @@ class FastAgent:
|
|
356
359
|
print(f"\n\nError sending message to agent '{agent_name}': {str(e)}")
|
357
360
|
raise SystemExit(1)
|
358
361
|
|
359
|
-
if self.args.prompt_file:
|
362
|
+
if hasattr(self.args, "prompt_file") and self.args.prompt_file:
|
360
363
|
agent_name = self.args.agent
|
361
364
|
prompt: List[PromptMessageMultipart] = load_prompt_multipart(
|
362
365
|
Path(self.args.prompt_file)
|
@@ -2,6 +2,7 @@ from abc import abstractmethod
|
|
2
2
|
from typing import (
|
3
3
|
TYPE_CHECKING,
|
4
4
|
Any,
|
5
|
+
Dict,
|
5
6
|
Generic,
|
6
7
|
List,
|
7
8
|
Optional,
|
@@ -59,7 +60,36 @@ if TYPE_CHECKING:
|
|
59
60
|
HUMAN_INPUT_TOOL_NAME = "__human_input__"
|
60
61
|
|
61
62
|
|
62
|
-
|
63
|
+
def deep_merge(dict1: Dict[Any, Any], dict2: Dict[Any, Any]) -> Dict[Any, Any]:
|
64
|
+
"""
|
65
|
+
Recursively merges `dict2` into `dict1` in place.
|
66
|
+
|
67
|
+
If a key exists in both dictionaries and their values are dictionaries,
|
68
|
+
the function merges them recursively. Otherwise, the value from `dict2`
|
69
|
+
overwrites or is added to `dict1`.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
dict1 (Dict): The dictionary to be updated.
|
73
|
+
dict2 (Dict): The dictionary to merge into `dict1`.
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
Dict: The updated `dict1`.
|
77
|
+
"""
|
78
|
+
for key in dict2:
|
79
|
+
if (
|
80
|
+
key in dict1
|
81
|
+
and isinstance(dict1[key], dict)
|
82
|
+
and isinstance(dict2[key], dict)
|
83
|
+
):
|
84
|
+
deep_merge(dict1[key], dict2[key])
|
85
|
+
else:
|
86
|
+
dict1[key] = dict2[key]
|
87
|
+
return dict1
|
88
|
+
|
89
|
+
|
90
|
+
class AugmentedLLM(
|
91
|
+
ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT, MessageT]
|
92
|
+
):
|
63
93
|
# Common parameter names used across providers
|
64
94
|
PARAM_MESSAGES = "messages"
|
65
95
|
PARAM_MODEL = "model"
|
@@ -357,8 +387,10 @@ class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT
|
|
357
387
|
) -> RequestParams:
|
358
388
|
"""Merge default and provided request parameters"""
|
359
389
|
|
360
|
-
merged =
|
361
|
-
|
390
|
+
merged = deep_merge(
|
391
|
+
default_params.model_dump(),
|
392
|
+
provided_params.model_dump(exclude_unset=True),
|
393
|
+
)
|
362
394
|
final_params = RequestParams(**merged)
|
363
395
|
|
364
396
|
return final_params
|
{fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_agent_client_session.py
RENAMED
@@ -3,6 +3,7 @@ A derived client session for the MCP Agent framework.
|
|
3
3
|
It adds logging and supports sampling requests.
|
4
4
|
"""
|
5
5
|
|
6
|
+
from datetime import timedelta
|
6
7
|
from typing import TYPE_CHECKING, Optional
|
7
8
|
|
8
9
|
from mcp import ClientSession
|
@@ -73,10 +74,13 @@ class MCPAgentClientSession(ClientSession, ContextDependent):
|
|
73
74
|
self,
|
74
75
|
request: SendRequestT,
|
75
76
|
result_type: type[ReceiveResultT],
|
77
|
+
request_read_timeout_seconds: timedelta | None = None,
|
76
78
|
) -> ReceiveResultT:
|
77
79
|
logger.debug("send_request: request=", data=request.model_dump())
|
78
80
|
try:
|
79
|
-
result = await super().send_request(
|
81
|
+
result = await super().send_request(
|
82
|
+
request, result_type, request_read_timeout_seconds=request_read_timeout_seconds
|
83
|
+
)
|
80
84
|
logger.debug("send_request: response=", data=result.model_dump())
|
81
85
|
return result
|
82
86
|
except Exception as e:
|
@@ -12,8 +12,6 @@ from typing import (
|
|
12
12
|
|
13
13
|
from mcp import GetPromptResult, ReadResourceResult
|
14
14
|
from mcp.client.session import ClientSession
|
15
|
-
from mcp.server.lowlevel.server import Server
|
16
|
-
from mcp.server.stdio import stdio_server
|
17
15
|
from mcp.types import (
|
18
16
|
CallToolResult,
|
19
17
|
ListToolsResult,
|
@@ -44,6 +42,16 @@ T = TypeVar("T")
|
|
44
42
|
R = TypeVar("R")
|
45
43
|
|
46
44
|
|
45
|
+
def create_namespaced_name(server_name: str, resource_name: str) -> str:
|
46
|
+
"""Create a namespaced resource name from server and resource names"""
|
47
|
+
return f"{server_name}{SEP}{resource_name}"
|
48
|
+
|
49
|
+
|
50
|
+
def is_namespaced_name(name: str) -> bool:
|
51
|
+
"""Check if a name is already namespaced"""
|
52
|
+
return SEP in name
|
53
|
+
|
54
|
+
|
47
55
|
class NamespacedTool(BaseModel):
|
48
56
|
"""
|
49
57
|
A tool that is namespaced by server name.
|
@@ -231,8 +239,7 @@ class MCPAggregator(ContextDependent):
|
|
231
239
|
|
232
240
|
async def fetch_prompts(client: ClientSession, server_name: str) -> List[Prompt]:
|
233
241
|
# Only fetch prompts if the server supports them
|
234
|
-
|
235
|
-
if not capabilities or not capabilities.prompts:
|
242
|
+
if not await self.server_supports_feature(server_name, "prompts"):
|
236
243
|
logger.debug(f"Server '{server_name}' does not support prompts")
|
237
244
|
return []
|
238
245
|
|
@@ -278,7 +285,7 @@ class MCPAggregator(ContextDependent):
|
|
278
285
|
# Process tools
|
279
286
|
self._server_to_tool_map[server_name] = []
|
280
287
|
for tool in tools:
|
281
|
-
namespaced_tool_name =
|
288
|
+
namespaced_tool_name = create_namespaced_name(server_name, tool.name)
|
282
289
|
namespaced_tool = NamespacedTool(
|
283
290
|
tool=tool,
|
284
291
|
server_name=server_name,
|
@@ -321,6 +328,41 @@ class MCPAggregator(ContextDependent):
|
|
321
328
|
logger.debug(f"Error getting capabilities for server '{server_name}': {e}")
|
322
329
|
return None
|
323
330
|
|
331
|
+
async def validate_server(self, server_name: str) -> bool:
|
332
|
+
"""
|
333
|
+
Validate that a server exists in our server list.
|
334
|
+
|
335
|
+
Args:
|
336
|
+
server_name: Name of the server to validate
|
337
|
+
|
338
|
+
Returns:
|
339
|
+
True if the server exists, False otherwise
|
340
|
+
"""
|
341
|
+
valid = server_name in self.server_names
|
342
|
+
if not valid:
|
343
|
+
logger.debug(f"Server '{server_name}' not found")
|
344
|
+
return valid
|
345
|
+
|
346
|
+
async def server_supports_feature(self, server_name: str, feature: str) -> bool:
|
347
|
+
"""
|
348
|
+
Check if a server supports a specific feature.
|
349
|
+
|
350
|
+
Args:
|
351
|
+
server_name: Name of the server to check
|
352
|
+
feature: Feature to check for (e.g., "prompts", "resources")
|
353
|
+
|
354
|
+
Returns:
|
355
|
+
True if the server supports the feature, False otherwise
|
356
|
+
"""
|
357
|
+
if not await self.validate_server(server_name):
|
358
|
+
return False
|
359
|
+
|
360
|
+
capabilities = await self.get_capabilities(server_name)
|
361
|
+
if not capabilities:
|
362
|
+
return False
|
363
|
+
|
364
|
+
return getattr(capabilities, feature, False)
|
365
|
+
|
324
366
|
async def list_servers(self) -> List[str]:
|
325
367
|
"""Return the list of server names aggregated by this agent."""
|
326
368
|
if not self.initialized:
|
@@ -420,40 +462,45 @@ class MCPAggregator(ContextDependent):
|
|
420
462
|
Returns:
|
421
463
|
Tuple of (server_name, local_resource_name)
|
422
464
|
"""
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
server_name,
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
#
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
465
|
+
# First, check if this is a direct hit in our namespaced tool map
|
466
|
+
# This handles both namespaced and non-namespaced direct lookups
|
467
|
+
if resource_type == "tool" and name in self._namespaced_tool_map:
|
468
|
+
namespaced_tool = self._namespaced_tool_map[name]
|
469
|
+
return namespaced_tool.server_name, namespaced_tool.tool.name
|
470
|
+
|
471
|
+
# Next, attempt to interpret as a namespaced name
|
472
|
+
if is_namespaced_name(name):
|
473
|
+
parts = name.split(SEP, 1)
|
474
|
+
server_name, local_name = parts[0], parts[1]
|
475
|
+
|
476
|
+
# Validate that the parsed server actually exists
|
477
|
+
if server_name in self.server_names:
|
478
|
+
return server_name, local_name
|
479
|
+
|
480
|
+
# If the server name doesn't exist, it might be a tool with a hyphen in its name
|
481
|
+
# Fall through to the next checks
|
482
|
+
|
483
|
+
# For tools, search all servers for the tool by exact name match
|
484
|
+
if resource_type == "tool":
|
485
|
+
for server_name, tools in self._server_to_tool_map.items():
|
486
|
+
for namespaced_tool in tools:
|
487
|
+
if namespaced_tool.tool.name == name:
|
488
|
+
return server_name, name
|
489
|
+
|
490
|
+
# For all other resource types, use the first server
|
491
|
+
return (self.server_names[0] if self.server_names else None, name)
|
446
492
|
|
447
493
|
async def call_tool(self, name: str, arguments: dict | None = None) -> CallToolResult:
|
448
494
|
"""
|
449
|
-
Call a namespaced tool, e.g., 'server_name
|
495
|
+
Call a namespaced tool, e.g., 'server_name-tool_name'.
|
450
496
|
"""
|
451
497
|
if not self.initialized:
|
452
498
|
await self.load_servers()
|
453
499
|
|
500
|
+
# Use the common parser to get server and tool name
|
454
501
|
server_name, local_tool_name = await self._parse_resource_name(name, "tool")
|
455
502
|
|
456
|
-
if server_name is None
|
503
|
+
if server_name is None:
|
457
504
|
logger.error(f"Error: Tool '{name}' not found")
|
458
505
|
return CallToolResult(
|
459
506
|
isError=True,
|
@@ -479,7 +526,10 @@ class MCPAggregator(ContextDependent):
|
|
479
526
|
operation_type="tool",
|
480
527
|
operation_name=local_tool_name,
|
481
528
|
method_name="call_tool",
|
482
|
-
method_args={
|
529
|
+
method_args={
|
530
|
+
"name": local_tool_name,
|
531
|
+
"arguments": arguments,
|
532
|
+
},
|
483
533
|
error_factory=lambda msg: CallToolResult(
|
484
534
|
isError=True, content=[TextContent(type="text", text=msg)]
|
485
535
|
),
|
@@ -506,18 +556,29 @@ class MCPAggregator(ContextDependent):
|
|
506
556
|
if not self.initialized:
|
507
557
|
await self.load_servers()
|
508
558
|
|
509
|
-
#
|
510
|
-
if
|
511
|
-
|
512
|
-
|
513
|
-
|
559
|
+
# If server_name is explicitly provided, use it
|
560
|
+
if server_name:
|
561
|
+
local_prompt_name = prompt_name
|
562
|
+
# Otherwise, check if prompt_name is namespaced and validate the server exists
|
563
|
+
elif is_namespaced_name(prompt_name):
|
564
|
+
parts = prompt_name.split(SEP, 1)
|
565
|
+
potential_server = parts[0]
|
566
|
+
|
567
|
+
# Only treat as namespaced if the server part is valid
|
568
|
+
if potential_server in self.server_names:
|
569
|
+
server_name = potential_server
|
570
|
+
local_prompt_name = parts[1]
|
571
|
+
else:
|
572
|
+
# The hyphen is part of the prompt name, not a namespace separator
|
573
|
+
local_prompt_name = prompt_name
|
574
|
+
# Otherwise, use prompt_name as-is for searching
|
514
575
|
else:
|
515
576
|
local_prompt_name = prompt_name
|
516
|
-
|
577
|
+
# We'll search all servers below
|
517
578
|
|
518
579
|
# If we have a specific server to check
|
519
580
|
if server_name:
|
520
|
-
if
|
581
|
+
if not await self.validate_server(server_name):
|
521
582
|
logger.error(f"Error: Server '{server_name}' not found")
|
522
583
|
return GetPromptResult(
|
523
584
|
description=f"Error: Server '{server_name}' not found",
|
@@ -525,8 +586,7 @@ class MCPAggregator(ContextDependent):
|
|
525
586
|
)
|
526
587
|
|
527
588
|
# Check if server supports prompts
|
528
|
-
|
529
|
-
if not capabilities or not capabilities.prompts:
|
589
|
+
if not await self.server_supports_feature(server_name, "prompts"):
|
530
590
|
logger.debug(f"Server '{server_name}' does not support prompts")
|
531
591
|
return GetPromptResult(
|
532
592
|
description=f"Server '{server_name}' does not support prompts",
|
@@ -564,7 +624,7 @@ class MCPAggregator(ContextDependent):
|
|
564
624
|
|
565
625
|
# Add namespaced name and source server to the result
|
566
626
|
if result and result.messages:
|
567
|
-
result.namespaced_name =
|
627
|
+
result.namespaced_name = create_namespaced_name(server_name, local_prompt_name)
|
568
628
|
|
569
629
|
# Store the arguments in the result for display purposes
|
570
630
|
if arguments:
|
@@ -616,7 +676,7 @@ class MCPAggregator(ContextDependent):
|
|
616
676
|
f"Successfully retrieved prompt '{local_prompt_name}' from server '{s_name}'"
|
617
677
|
)
|
618
678
|
# Add namespaced name using the actual server where found
|
619
|
-
result.namespaced_name =
|
679
|
+
result.namespaced_name = create_namespaced_name(s_name, local_prompt_name)
|
620
680
|
|
621
681
|
# Store the arguments in the result for display purposes
|
622
682
|
if arguments:
|
@@ -664,7 +724,7 @@ class MCPAggregator(ContextDependent):
|
|
664
724
|
f"Found prompt '{local_prompt_name}' on server '{s_name}' (not in cache)"
|
665
725
|
)
|
666
726
|
# Add namespaced name using the actual server where found
|
667
|
-
result.namespaced_name =
|
727
|
+
result.namespaced_name = create_namespaced_name(s_name, local_prompt_name)
|
668
728
|
|
669
729
|
# Store the arguments in the result for display purposes
|
670
730
|
if arguments:
|
@@ -942,68 +1002,3 @@ class MCPAggregator(ContextDependent):
|
|
942
1002
|
logger.error(f"Error fetching resources from {s_name}: {e}")
|
943
1003
|
|
944
1004
|
return results
|
945
|
-
|
946
|
-
|
947
|
-
class MCPCompoundServer(Server):
|
948
|
-
"""
|
949
|
-
A compound server (server-of-servers) that aggregates multiple MCP servers and is itself an MCP server
|
950
|
-
"""
|
951
|
-
|
952
|
-
def __init__(self, server_names: List[str], name: str = "MCPCompoundServer") -> None:
|
953
|
-
super().__init__(name)
|
954
|
-
self.aggregator = MCPAggregator(server_names)
|
955
|
-
|
956
|
-
# Register handlers for tools, prompts, and resources
|
957
|
-
self.list_tools()(self._list_tools)
|
958
|
-
self.call_tool()(self._call_tool)
|
959
|
-
self.get_prompt()(self._get_prompt)
|
960
|
-
self.list_prompts()(self._list_prompts)
|
961
|
-
|
962
|
-
async def _list_tools(self) -> List[Tool]:
|
963
|
-
"""List all tools aggregated from connected MCP servers."""
|
964
|
-
tools_result = await self.aggregator.list_tools()
|
965
|
-
return tools_result.tools
|
966
|
-
|
967
|
-
async def _call_tool(self, name: str, arguments: dict | None = None) -> CallToolResult:
|
968
|
-
"""Call a specific tool from the aggregated servers."""
|
969
|
-
try:
|
970
|
-
result = await self.aggregator.call_tool(name=name, arguments=arguments)
|
971
|
-
return result.content
|
972
|
-
except Exception as e:
|
973
|
-
return CallToolResult(
|
974
|
-
isError=True,
|
975
|
-
content=[TextContent(type="text", text=f"Error calling tool: {e}")],
|
976
|
-
)
|
977
|
-
|
978
|
-
async def _get_prompt(
|
979
|
-
self, name: str = None, arguments: dict[str, str] = None
|
980
|
-
) -> GetPromptResult:
|
981
|
-
"""
|
982
|
-
Get a prompt from the aggregated servers.
|
983
|
-
|
984
|
-
Args:
|
985
|
-
name: Name of the prompt to get (optionally namespaced)
|
986
|
-
arguments: Optional dictionary of string arguments for prompt templating
|
987
|
-
"""
|
988
|
-
try:
|
989
|
-
result = await self.aggregator.get_prompt(prompt_name=name, arguments=arguments)
|
990
|
-
return result
|
991
|
-
except Exception as e:
|
992
|
-
return GetPromptResult(description=f"Error getting prompt: {e}", messages=[])
|
993
|
-
|
994
|
-
async def _list_prompts(self, server_name: str = None) -> Dict[str, List[Prompt]]:
|
995
|
-
"""List available prompts from the aggregated servers."""
|
996
|
-
try:
|
997
|
-
return await self.aggregator.list_prompts(server_name=server_name)
|
998
|
-
except Exception as e:
|
999
|
-
logger.error(f"Error listing prompts: {e}")
|
1000
|
-
return {}
|
1001
|
-
|
1002
|
-
async def run_stdio_async(self) -> None:
|
1003
|
-
"""Run the server using stdio transport."""
|
1004
|
-
async with stdio_server() as (read_stream, write_stream):
|
1005
|
-
await self.run(
|
1006
|
-
read_stream=read_stream,
|
1007
|
-
write_stream=write_stream,
|
1008
|
-
initialization_options=self.create_initialization_options(),
|
1009
|
-
)
|
@@ -264,6 +264,7 @@ class MCPConnectionManager(ContextDependent):
|
|
264
264
|
command=config.command,
|
265
265
|
args=config.args if config.args is not None else [],
|
266
266
|
env={**get_default_environment(), **(config.env or {})},
|
267
|
+
cwd=config.cwd,
|
267
268
|
)
|
268
269
|
# Create custom error handler to ensure all output is captured
|
269
270
|
error_handler = get_stderr_handler(server_name)
|
@@ -82,6 +82,7 @@ class PromptConfig(PromptMetadata):
|
|
82
82
|
http_timeout: float = 10.0
|
83
83
|
transport: str = "stdio"
|
84
84
|
port: int = 8000
|
85
|
+
host: str = "0.0.0.0"
|
85
86
|
|
86
87
|
|
87
88
|
# We'll maintain registries of all exposed resources and prompts
|
@@ -344,6 +345,12 @@ def parse_args():
|
|
344
345
|
default=8000,
|
345
346
|
help="Port to use for SSE transport (default: 8000)",
|
346
347
|
)
|
348
|
+
parser.add_argument(
|
349
|
+
"--host",
|
350
|
+
type=str,
|
351
|
+
default="0.0.0.0",
|
352
|
+
help="Host to bind to for SSE transport (default: 0.0.0.0)",
|
353
|
+
)
|
347
354
|
parser.add_argument(
|
348
355
|
"--test", type=str, help="Test a specific prompt without starting the server"
|
349
356
|
)
|
@@ -380,6 +387,7 @@ def initialize_config(args) -> PromptConfig:
|
|
380
387
|
http_timeout=args.http_timeout,
|
381
388
|
transport=args.transport,
|
382
389
|
port=args.port,
|
390
|
+
host=args.host,
|
383
391
|
)
|
384
392
|
|
385
393
|
|
@@ -497,7 +505,10 @@ async def async_main() -> int:
|
|
497
505
|
if config.transport == "stdio":
|
498
506
|
await mcp.run_stdio_async()
|
499
507
|
else: # sse
|
500
|
-
#
|
508
|
+
# Set the host and port in settings before running the server
|
509
|
+
mcp.settings.host = config.host
|
510
|
+
mcp.settings.port = config.port
|
511
|
+
logger.info(f"Starting SSE server on {config.host}:{config.port}")
|
501
512
|
await mcp.run_sse_async()
|
502
513
|
return 0
|
503
514
|
|
@@ -110,7 +110,10 @@ class AgentMCPServer:
|
|
110
110
|
|
111
111
|
# Register handlers for SIGINT (Ctrl+C) and SIGTERM
|
112
112
|
for sig, is_term in [(signal.SIGINT, False), (signal.SIGTERM, True)]:
|
113
|
-
|
113
|
+
import platform
|
114
|
+
|
115
|
+
if platform.system() != "Windows":
|
116
|
+
loop.add_signal_handler(sig, lambda term=is_term: handle_signal(term))
|
114
117
|
|
115
118
|
logger.debug("Signal handlers installed")
|
116
119
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/fastagent.config.yaml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/fastagent.config.yaml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/fastagent.config.yaml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|