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.
Files changed (179) hide show
  1. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/PKG-INFO +2 -2
  2. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/pyproject.toml +2 -2
  3. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/__init__.py +1 -2
  4. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/config.py +3 -0
  5. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/context.py +2 -1
  6. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/fastagent.py +5 -2
  7. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm.py +35 -3
  8. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +1 -1
  9. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_openai.py +1 -1
  10. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_agent_client_session.py +5 -1
  11. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_aggregator.py +103 -108
  12. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mcp_connection_manager.py +1 -0
  13. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_server.py +12 -1
  14. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server/agent_server.py +4 -1
  15. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server_registry.py +1 -0
  16. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/.gitignore +0 -0
  17. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/LICENSE +0 -0
  18. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/README.md +0 -0
  19. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/analysis-campaign.py +0 -0
  20. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/analysis.py +0 -0
  21. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/data-analysis/fastagent.config.yaml +0 -0
  22. {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
  23. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/agent_one.py +0 -0
  24. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/agent_two.py +0 -0
  25. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
  26. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example1.py +0 -0
  27. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example2.py +0 -0
  28. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/example3.py +0 -0
  29. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
  30. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/agent.py +0 -0
  31. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/agent2.py +0 -0
  32. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/docker-compose.yaml +0 -0
  33. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/otel/fastagent.config.yaml +0 -0
  34. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/fastagent.config.yaml +0 -0
  35. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher-eval.py +0 -0
  36. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher-imp.py +0 -0
  37. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/researcher/researcher.py +0 -0
  38. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/chaining.py +0 -0
  39. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/evaluator.py +0 -0
  40. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/fastagent.config.yaml +0 -0
  41. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/graded_report.md +0 -0
  42. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/human_input.py +0 -0
  43. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/orchestrator.py +0 -0
  44. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/parallel.py +0 -0
  45. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/router.py +0 -0
  46. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/short_story.md +0 -0
  47. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/examples/workflows/short_story.txt +0 -0
  48. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/__init__.py +0 -0
  49. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/agent.py +0 -0
  50. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/base_agent.py +0 -0
  51. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/__init__.py +0 -0
  52. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
  53. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
  54. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
  55. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
  56. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
  57. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
  58. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/agents/workflow/router_agent.py +0 -0
  59. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/app.py +0 -0
  60. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/__init__.py +0 -0
  61. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/__main__.py +0 -0
  62. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/check_config.py +0 -0
  63. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/go.py +0 -0
  64. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/quickstart.py +0 -0
  65. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/commands/setup.py +0 -0
  66. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/main.py +0 -0
  67. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/cli/terminal.py +0 -0
  68. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/console.py +0 -0
  69. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/context_dependent.py +0 -0
  70. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/__init__.py +0 -0
  71. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/agent_app.py +0 -0
  72. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/agent_types.py +0 -0
  73. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/direct_decorators.py +0 -0
  74. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/direct_factory.py +0 -0
  75. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/enhanced_prompt.py +0 -0
  76. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/error_handling.py +0 -0
  77. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/exceptions.py +0 -0
  78. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/interactive_prompt.py +0 -0
  79. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/mcp_content.py +0 -0
  80. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/prompt.py +0 -0
  81. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/request_params.py +0 -0
  82. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/core/validation.py +0 -0
  83. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/event_progress.py +0 -0
  84. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/__init__.py +0 -0
  85. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/executor.py +0 -0
  86. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/task_registry.py +0 -0
  87. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/executor/workflow_signal.py +0 -0
  88. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/__init__.py +0 -0
  89. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/handler.py +0 -0
  90. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/human_input/types.py +0 -0
  91. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/__init__.py +0 -0
  92. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
  93. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
  94. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/memory.py +0 -0
  95. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/model_factory.py +0 -0
  96. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/prompt_utils.py +0 -0
  97. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/provider_key_manager.py +0 -0
  98. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/provider_types.py +0 -0
  99. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/__init__.py +0 -0
  100. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
  101. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
  102. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
  103. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_google.py +0 -0
  104. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
  105. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
  106. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
  107. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
  108. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
  109. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
  110. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
  111. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/sampling_converter.py +0 -0
  112. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
  113. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/__init__.py +0 -0
  114. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/events.py +0 -0
  115. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/json_serializer.py +0 -0
  116. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/listeners.py +0 -0
  117. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/logger.py +0 -0
  118. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/rich_progress.py +0 -0
  119. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/logging/transport.py +0 -0
  120. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/__init__.py +0 -0
  121. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/gen_client.py +0 -0
  122. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
  123. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
  124. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/interfaces.py +0 -0
  125. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/logger_textio.py +0 -0
  126. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/mime_utils.py +0 -0
  127. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
  128. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_render.py +0 -0
  129. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
  130. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  131. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  132. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
  133. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
  134. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
  135. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
  136. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/resource_utils.py +0 -0
  137. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp/sampling.py +0 -0
  138. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/mcp_server/__init__.py +0 -0
  139. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/progress_display.py +0 -0
  140. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
  141. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
  142. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  143. {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
  144. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -0
  145. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -0
  146. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
  147. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
  148. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
  149. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
  150. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/job.py +0 -0
  151. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
  152. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
  153. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/simple.txt +0 -0
  154. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
  155. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/internal/social.py +0 -0
  156. {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
  157. {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
  158. {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
  159. {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
  160. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
  161. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/agent.py +0 -0
  162. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -0
  163. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
  164. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
  165. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -0
  166. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
  167. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  168. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  169. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
  170. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  171. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  172. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
  173. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  174. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  175. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
  176. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
  177. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  178. {fast_agent_mcp-0.2.19 → fast_agent_mcp-0.2.21}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
  179. {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.19
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==1.6.0
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.19"
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==1.6.0",
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, MCPCompoundServer
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
- class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT, MessageT]):
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 = default_params.model_dump()
361
- merged.update(provided_params.model_dump(exclude_unset=True))
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
@@ -79,7 +79,7 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
79
79
  maxTokens=4096, # default haiku3
80
80
  systemPrompt=self.instruction,
81
81
  parallel_tool_calls=True,
82
- max_iterations=10,
82
+ max_iterations=20,
83
83
  use_history=True,
84
84
  )
85
85
 
@@ -95,7 +95,7 @@ class OpenAIAugmentedLLM(AugmentedLLM[ChatCompletionMessageParam, ChatCompletion
95
95
  model=chosen_model,
96
96
  systemPrompt=self.instruction,
97
97
  parallel_tool_calls=True,
98
- max_iterations=10,
98
+ max_iterations=20,
99
99
  use_history=True,
100
100
  )
101
101
 
@@ -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(request, result_type)
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
- capabilities = await self.get_capabilities(server_name)
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 = f"{server_name}{SEP}{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
- server_name = None
424
- local_name = None
425
-
426
- if SEP in name: # Namespaced resource name
427
- server_name, local_name = name.split(SEP, 1)
428
- else:
429
- # For tools, search all servers for the tool
430
- if resource_type == "tool":
431
- for _, tools in self._server_to_tool_map.items():
432
- for namespaced_tool in tools:
433
- if namespaced_tool.tool.name == name:
434
- server_name = namespaced_tool.server_name
435
- local_name = name
436
- break
437
- if server_name:
438
- break
439
- # For all other resource types, use the first server
440
- # (prompt resource type is specially handled in get_prompt)
441
- else:
442
- local_name = name
443
- server_name = self.server_names[0] if self.server_names else None
444
-
445
- return server_name, local_name
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.tool_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 or local_tool_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={"name": local_tool_name, "arguments": arguments},
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
- # Handle the case where prompt_name is None
510
- if SEP in prompt_name and server_name is None:
511
- server_name, local_prompt_name = prompt_name.split(SEP, 1)
512
- namespaced_name = prompt_name # Already namespaced
513
- # Plain prompt name - use provided server or search
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
- namespaced_name = None # Will be set when server is found
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 server_name not in self.server_names:
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
- capabilities = await self.get_capabilities(server_name)
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 = namespaced_name or f"{server_name}{SEP}{local_prompt_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 = f"{s_name}{SEP}{local_prompt_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 = f"{s_name}{SEP}{local_prompt_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
- # TODO update to 2025-03-26 specification and test config.
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
- loop.add_signal_handler(sig, lambda term=is_term: handle_signal(term))
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
 
@@ -128,6 +128,7 @@ class ServerRegistry:
128
128
  command=config.command,
129
129
  args=config.args,
130
130
  env={**get_default_environment(), **(config.env or {})},
131
+ cwd=config.cwd,
131
132
  )
132
133
 
133
134
  # Create a stderr handler that logs to our application logger
File without changes