fast-agent-mcp 0.1.8__tar.gz → 0.1.10__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 (163) hide show
  1. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/PKG-INFO +27 -4
  2. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/README.md +25 -2
  3. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/pyproject.toml +15 -3
  4. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/agents/agent.py +114 -8
  5. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/context.py +0 -2
  6. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/agent_app.py +89 -13
  7. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/factory.py +14 -13
  8. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/fastagent.py +15 -5
  9. fast_agent_mcp-0.1.10/src/mcp_agent/core/mcp_content.py +222 -0
  10. fast_agent_mcp-0.1.10/src/mcp_agent/core/prompt.py +132 -0
  11. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/proxies.py +79 -36
  12. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/listeners.py +3 -6
  13. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/transport.py +30 -3
  14. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/mcp_agent_client_session.py +118 -0
  15. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/mcp_aggregator.py +61 -12
  16. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/mcp_connection_manager.py +0 -1
  17. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/mime_utils.py +69 -0
  18. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompt_message_multipart.py +64 -0
  19. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompt_serialization.py +447 -0
  20. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompts/__main__.py +10 -0
  21. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompts/prompt_server.py +509 -0
  22. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompts/prompt_template.py +469 -0
  23. fast_agent_mcp-0.1.10/src/mcp_agent/mcp/resource_utils.py +223 -0
  24. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/stdio.py +23 -15
  25. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp_server_registry.py +5 -2
  26. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/agent.py +1 -1
  27. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +2 -2
  28. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/sizer.py +0 -5
  29. fast_agent_mcp-0.1.10/src/mcp_agent/resources/examples/prompting/__init__.py +3 -0
  30. fast_agent_mcp-0.1.10/src/mcp_agent/resources/examples/prompting/agent.py +23 -0
  31. fast_agent_mcp-0.1.10/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +44 -0
  32. fast_agent_mcp-0.1.10/src/mcp_agent/resources/examples/prompting/image_server.py +56 -0
  33. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/orchestrator.py +3 -3
  34. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/anthropic_utils.py +101 -0
  35. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/augmented_llm.py +139 -66
  36. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/augmented_llm_anthropic.py +127 -251
  37. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/augmented_llm_openai.py +149 -305
  38. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/augmented_llm_passthrough.py +159 -0
  39. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/augmented_llm_playback.py +109 -0
  40. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/model_factory.py +20 -3
  41. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/openai_utils.py +65 -0
  42. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/__init__.py +8 -0
  43. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/multipart_converter_anthropic.py +348 -0
  44. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/multipart_converter_openai.py +426 -0
  45. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/openai_multipart.py +197 -0
  46. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/sampling_converter_anthropic.py +258 -0
  47. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/providers/sampling_converter_openai.py +229 -0
  48. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm/sampling_format_converter.py +39 -0
  49. fast_agent_mcp-0.1.10/src/mcp_agent/workflows/swarm/__init__.py +0 -0
  50. fast_agent_mcp-0.1.8/src/mcp_agent/core/server_validation.py +0 -44
  51. fast_agent_mcp-0.1.8/src/mcp_agent/core/simulator_registry.py +0 -22
  52. fast_agent_mcp-0.1.8/src/mcp_agent/mcp/mcp_agent_client_session.py +0 -242
  53. fast_agent_mcp-0.1.8/src/mcp_agent/workflows/llm/augmented_llm_passthrough.py +0 -61
  54. fast_agent_mcp-0.1.8/src/mcp_agent/workflows/llm/enhanced_passthrough.py +0 -70
  55. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/.gitignore +0 -0
  56. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/LICENSE +0 -0
  57. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/__init__.py +0 -0
  58. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/agents/__init__.py +0 -0
  59. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/app.py +0 -0
  60. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/__init__.py +0 -0
  61. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/__main__.py +0 -0
  62. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/commands/bootstrap.py +0 -0
  63. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/commands/config.py +0 -0
  64. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/commands/setup.py +0 -0
  65. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/main.py +0 -0
  66. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/cli/terminal.py +0 -0
  67. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/config.py +0 -0
  68. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/console.py +0 -0
  69. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/context_dependent.py +0 -0
  70. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/__init__.py +0 -0
  71. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/agent_types.py +0 -0
  72. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/agent_utils.py +0 -0
  73. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/decorators.py +0 -0
  74. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/enhanced_prompt.py +0 -0
  75. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/error_handling.py +0 -0
  76. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/exceptions.py +0 -0
  77. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/types.py +0 -0
  78. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/core/validation.py +0 -0
  79. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/eval/__init__.py +0 -0
  80. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/event_progress.py +0 -0
  81. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/__init__.py +0 -0
  82. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/decorator_registry.py +0 -0
  83. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/executor.py +0 -0
  84. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/task_registry.py +0 -0
  85. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/temporal.py +0 -0
  86. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/workflow.py +0 -0
  87. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/executor/workflow_signal.py +0 -0
  88. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/human_input/__init__.py +0 -0
  89. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/human_input/handler.py +0 -0
  90. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/human_input/types.py +0 -0
  91. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/__init__.py +0 -0
  92. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/events.py +0 -0
  93. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/json_serializer.py +0 -0
  94. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/logger.py +0 -0
  95. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/rich_progress.py +0 -0
  96. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/logging/tracing.py +0 -0
  97. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/__init__.py +0 -0
  98. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/gen_client.py +0 -0
  99. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/mcp_activity.py +0 -0
  100. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp/mcp_agent_server.py +0 -0
  101. {fast_agent_mcp-0.1.8/src/mcp_agent/telemetry → fast_agent_mcp-0.1.10/src/mcp_agent/mcp/prompts}/__init__.py +0 -0
  102. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp_server/__init__.py +0 -0
  103. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/mcp_server/agent_server.py +0 -0
  104. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/progress_display.py +0 -0
  105. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
  106. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
  107. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  108. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  109. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/job.py +0 -0
  110. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
  111. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
  112. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/internal/social.py +0 -0
  113. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +0 -0
  114. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  115. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  116. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
  117. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  118. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/agent_build.py +0 -0
  119. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  120. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
  121. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  122. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  123. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
  124. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  125. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/resources/examples/workflows/sse.py +0 -0
  126. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows → fast_agent_mcp-0.1.10/src/mcp_agent/telemetry}/__init__.py +0 -0
  127. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/telemetry/usage_tracking.py +0 -0
  128. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/ui/console_display.py +0 -0
  129. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/embedding → fast_agent_mcp-0.1.10/src/mcp_agent/workflows}/__init__.py +0 -0
  130. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/evaluator_optimizer → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/embedding}/__init__.py +0 -0
  131. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/embedding/embedding_base.py +0 -0
  132. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/embedding/embedding_cohere.py +0 -0
  133. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/embedding/embedding_openai.py +0 -0
  134. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/intent_classifier → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/evaluator_optimizer}/__init__.py +0 -0
  135. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +0 -0
  136. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/llm → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/intent_classifier}/__init__.py +0 -0
  137. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_base.py +0 -0
  138. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +0 -0
  139. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +0 -0
  140. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +0 -0
  141. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +0 -0
  142. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +0 -0
  143. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +0 -0
  144. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/orchestrator → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/llm}/__init__.py +0 -0
  145. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/llm_selector.py +0 -0
  146. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/llm/prompt_utils.py +0 -0
  147. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/parallel → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/orchestrator}/__init__.py +0 -0
  148. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/orchestrator/orchestrator.py +0 -0
  149. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/orchestrator/orchestrator_models.py +0 -0
  150. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/orchestrator/orchestrator_prompts.py +0 -0
  151. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/router → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/parallel}/__init__.py +0 -0
  152. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/parallel/fan_in.py +0 -0
  153. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/parallel/fan_out.py +0 -0
  154. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/parallel/parallel_llm.py +0 -0
  155. {fast_agent_mcp-0.1.8/src/mcp_agent/workflows/swarm → fast_agent_mcp-0.1.10/src/mcp_agent/workflows/router}/__init__.py +0 -0
  156. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/router/router_base.py +0 -0
  157. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/router/router_embedding.py +0 -0
  158. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/router/router_embedding_cohere.py +0 -0
  159. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/router/router_embedding_openai.py +0 -0
  160. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/router/router_llm.py +0 -0
  161. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/swarm/swarm.py +0 -0
  162. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/swarm/swarm_anthropic.py +0 -0
  163. {fast_agent_mcp-0.1.8 → fast_agent_mcp-0.1.10}/src/mcp_agent/workflows/swarm/swarm_openai.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.1.8
3
+ Version: 0.1.10
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
@@ -212,7 +212,7 @@ Requires-Python: >=3.10
212
212
  Requires-Dist: aiohttp>=3.11.13
213
213
  Requires-Dist: anthropic>=0.49.0
214
214
  Requires-Dist: fastapi>=0.115.6
215
- Requires-Dist: mcp==1.2.1
215
+ Requires-Dist: mcp>=1.4.1
216
216
  Requires-Dist: numpy>=2.2.1
217
217
  Requires-Dist: openai>=1.63.2
218
218
  Requires-Dist: opentelemetry-distro>=0.50b0
@@ -259,6 +259,11 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
259
259
 
260
260
  Evaluate how different models handle Agent and MCP Server calling tasks, then build multi-model workflows using the best provider for each task.
261
261
 
262
+ `fast-agent` is now multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints (for supported models), via Prompts, Resources and MCP Tool Call results.
263
+
264
+ > [!TIP]
265
+ > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site.
266
+
262
267
  ### Agent Application Development
263
268
 
264
269
  Prompts and configurations that define your Agent Applications are stored in simple files, with minimal boilerplate, enabling simple management and version control.
@@ -588,6 +593,19 @@ agent["greeter"].send("Good Evening!") # Dictionary access is supported
588
593
  )
589
594
  ```
590
595
 
596
+ ### Multimodal Support
597
+
598
+ Add Resources to prompts using either the inbuilt `prompt-server` or MCP Types directly. Convenience class are made available to do so simply, for example:
599
+
600
+ #### MCP Tool Result Conversion
601
+
602
+ LLM APIs have restrictions on the content types that can be returned as Tool Calls/Function results via their Chat Completions API's:
603
+
604
+ - OpenAI supports Text
605
+ - Anthropic supports Text and Image
606
+
607
+ For MCP Tool Results, `ImageResources` and `EmbeddedResources` are converted to User Messages and added to the conversation.
608
+
591
609
  ### Prompts
592
610
 
593
611
  MCP Prompts are supported with `apply_prompt(name,arguments)`, which always returns an Assistant Message. If the last message from the MCP Server is a 'User' message, it is sent to the LLM for processing. Prompts applied to the Agent's Context are retained - meaning that with `use_history=False`, Agents can act as finely tuned responders.
@@ -605,8 +623,9 @@ Prompts can also be applied interactively through the interactive interface by u
605
623
 
606
624
  ### llmindset.co.uk fork:
607
625
 
626
+ - Addition of MCP Prompts including Prompt Server and agent save/replay ability.
608
627
  - Overhaul of Eval/Opt for Conversation Management
609
- - Remove instructor use for Orchestrator
628
+ - Removed instructor/double-llm calling - native structured outputs for OAI.
610
629
  - Improved handling of Parallel/Fan-In and respose option
611
630
  - XML based generated prompts
612
631
  - "FastAgent" style prototyping, with per-agent models
@@ -625,4 +644,8 @@ Prompts can also be applied interactively through the interactive interface by u
625
644
  - Declarative workflows
626
645
  - Numerous defect fixes
627
646
 
628
- ### Features to add.
647
+ ### Features to add (Commmitted)
648
+
649
+ - Run Agent as MCP Server, with interop
650
+ - Multi-part content types supporing Vision, PDF and multi-part Text.
651
+ - Improved test automation (supported by prompt_server.py and augmented_llm_playback.py)
@@ -16,6 +16,11 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
16
16
 
17
17
  Evaluate how different models handle Agent and MCP Server calling tasks, then build multi-model workflows using the best provider for each task.
18
18
 
19
+ `fast-agent` is now multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints (for supported models), via Prompts, Resources and MCP Tool Call results.
20
+
21
+ > [!TIP]
22
+ > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site.
23
+
19
24
  ### Agent Application Development
20
25
 
21
26
  Prompts and configurations that define your Agent Applications are stored in simple files, with minimal boilerplate, enabling simple management and version control.
@@ -345,6 +350,19 @@ agent["greeter"].send("Good Evening!") # Dictionary access is supported
345
350
  )
346
351
  ```
347
352
 
353
+ ### Multimodal Support
354
+
355
+ Add Resources to prompts using either the inbuilt `prompt-server` or MCP Types directly. Convenience class are made available to do so simply, for example:
356
+
357
+ #### MCP Tool Result Conversion
358
+
359
+ LLM APIs have restrictions on the content types that can be returned as Tool Calls/Function results via their Chat Completions API's:
360
+
361
+ - OpenAI supports Text
362
+ - Anthropic supports Text and Image
363
+
364
+ For MCP Tool Results, `ImageResources` and `EmbeddedResources` are converted to User Messages and added to the conversation.
365
+
348
366
  ### Prompts
349
367
 
350
368
  MCP Prompts are supported with `apply_prompt(name,arguments)`, which always returns an Assistant Message. If the last message from the MCP Server is a 'User' message, it is sent to the LLM for processing. Prompts applied to the Agent's Context are retained - meaning that with `use_history=False`, Agents can act as finely tuned responders.
@@ -362,8 +380,9 @@ Prompts can also be applied interactively through the interactive interface by u
362
380
 
363
381
  ### llmindset.co.uk fork:
364
382
 
383
+ - Addition of MCP Prompts including Prompt Server and agent save/replay ability.
365
384
  - Overhaul of Eval/Opt for Conversation Management
366
- - Remove instructor use for Orchestrator
385
+ - Removed instructor/double-llm calling - native structured outputs for OAI.
367
386
  - Improved handling of Parallel/Fan-In and respose option
368
387
  - XML based generated prompts
369
388
  - "FastAgent" style prototyping, with per-agent models
@@ -382,4 +401,8 @@ Prompts can also be applied interactively through the interactive interface by u
382
401
  - Declarative workflows
383
402
  - Numerous defect fixes
384
403
 
385
- ### Features to add.
404
+ ### Features to add (Commmitted)
405
+
406
+ - Run Agent as MCP Server, with interop
407
+ - Multi-part content types supporing Vision, PDF and multi-part Text.
408
+ - Improved test automation (supported by prompt_server.py and augmented_llm_playback.py)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fast-agent-mcp"
3
- version = "0.1.8"
3
+ version = "0.1.10"
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.2.1",
19
+ "mcp>=1.4.1",
20
20
  "opentelemetry-distro>=0.50b0",
21
21
  "opentelemetry-exporter-otlp-proto-http>=1.29.0",
22
22
  "pydantic-settings>=2.7.0",
@@ -72,9 +72,20 @@ include = [
72
72
  "src/mcp_agent/resources/**/*.csv",
73
73
  ]
74
74
 
75
+ [tool.pytest.ini_options]
76
+ asyncio_mode = "strict"
77
+ asyncio_default_fixture_loop_scope = "function"
78
+ markers = [
79
+ "e2e: tests that connect to external resources (llms)",
80
+ "integration: marks tests as integration tests",
81
+ "simulated_endpoints: marks tests that use simulated external endpoints"
82
+ ]
83
+ # Other pytest options can go here too
84
+ testpaths = ["test", "integration_tests"]
85
+
75
86
  [dependency-groups]
76
87
  dev = [
77
- "anthropic>=0.42.0",
88
+ "anthropic>=0.49.0",
78
89
  "pre-commit>=4.0.1",
79
90
  "pydantic>=2.10.4",
80
91
  "pyyaml>=6.0.2",
@@ -89,6 +100,7 @@ fast-agent = "mcp_agent.cli.__main__:app"
89
100
  fast_agent = "mcp_agent.cli.__main__:app"
90
101
  fastagent = "mcp_agent.cli.__main__:app"
91
102
  silsila = "mcp_agent.cli.__main__:app"
103
+ prompt-server = "mcp_agent.mcp.prompts.__main__:main"
92
104
 
93
105
  [tool.setuptools.package-data]
94
106
  mcp_agent = [
@@ -9,7 +9,10 @@ from mcp.types import (
9
9
  ListToolsResult,
10
10
  TextContent,
11
11
  Tool,
12
+ EmbeddedResource,
13
+ ReadResourceResult,
12
14
  )
15
+ from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
13
16
 
14
17
  from mcp_agent.core.exceptions import PromptExitError
15
18
  from mcp_agent.mcp.mcp_aggregator import MCPAggregator
@@ -320,18 +323,25 @@ class Agent(MCPAggregator):
320
323
  ],
321
324
  )
322
325
 
323
- async def apply_prompt(self, prompt_name: str, arguments: dict[str, str] = None) -> str:
326
+ async def read_resource(
327
+ self, server_name: str, resource_name: str
328
+ ) -> ReadResourceResult:
329
+ return None
330
+
331
+ async def apply_prompt(
332
+ self, prompt_name: str, arguments: dict[str, str] = None
333
+ ) -> str:
324
334
  """
325
335
  Apply an MCP Server Prompt by name and return the assistant's response.
326
336
  Will search all available servers for the prompt if not namespaced.
327
-
337
+
328
338
  If the last message in the prompt is from a user, this will automatically
329
339
  generate an assistant response to ensure we always end with an assistant message.
330
340
 
331
341
  Args:
332
342
  prompt_name: The name of the prompt to apply
333
343
  arguments: Optional dictionary of string arguments to pass to the prompt template
334
-
344
+
335
345
  Returns:
336
346
  The assistant's response or error message
337
347
  """
@@ -358,10 +368,106 @@ class Agent(MCPAggregator):
358
368
  result = await self._llm.apply_prompt_template(prompt_result, display_name)
359
369
  return result
360
370
 
361
- # For backward compatibility
362
- async def load_prompt(self, prompt_name: str, arguments: dict[str, str] = None) -> str:
371
+ async def get_resource(self, server_name: str, resource_name: str):
372
+ """
373
+ Get a resource directly from an MCP server by name.
374
+
375
+ Args:
376
+ server_name: Name of the MCP server to retrieve the resource from
377
+ resource_name: Name of the resource to retrieve
378
+
379
+ Returns:
380
+ The resource object from the MCP server
381
+
382
+ Raises:
383
+ ValueError: If the server doesn't exist or the resource couldn't be found
384
+ """
385
+ if not self.initialized:
386
+ await self.initialize()
387
+
388
+ # Get the specified server connection
389
+ server = self.get_server(server_name)
390
+ if not server:
391
+ raise ValueError(f"Server '{server_name}' not found or not connected")
392
+
393
+ # Request the resource directly from the server
394
+ try:
395
+ resource_result = await server.get_resource(resource_name)
396
+ return resource_result
397
+ except Exception as e:
398
+ self.logger.error(
399
+ f"Error retrieving resource '{resource_name}' from server '{server_name}': {str(e)}"
400
+ )
401
+ raise ValueError(
402
+ f"Failed to retrieve resource '{resource_name}' from server '{server_name}': {str(e)}"
403
+ )
404
+
405
+ async def get_embedded_resources(
406
+ self, server_name: str, resource_name: str
407
+ ) -> List[EmbeddedResource]:
408
+ """
409
+ Get a resource from an MCP server and return it as a list of embedded resources ready for use in prompts.
410
+
411
+ Args:
412
+ server_name: Name of the MCP server to retrieve the resource from
413
+ resource_name: Name or URI of the resource to retrieve
414
+
415
+ Returns:
416
+ List of EmbeddedResource objects ready to use in a PromptMessageMultipart
417
+
418
+ Raises:
419
+ ValueError: If the server doesn't exist or the resource couldn't be found
363
420
  """
364
- Legacy method - use apply_prompt instead.
365
- This is maintained for backward compatibility.
421
+ # Get the raw resource result
422
+ result: ReadResourceResult = await super().get_resource(
423
+ server_name, resource_name
424
+ )
425
+
426
+ # Convert each resource content to an EmbeddedResource
427
+ embedded_resources: List[EmbeddedResource] = []
428
+ for resource_content in result.contents:
429
+ embedded_resource = EmbeddedResource(
430
+ type="resource", resource=resource_content, annotations=None
431
+ )
432
+ embedded_resources.append(embedded_resource)
433
+
434
+ return embedded_resources
435
+
436
+ async def with_resource(
437
+ self,
438
+ prompt_content: Union[str, PromptMessageMultipart],
439
+ server_name: str,
440
+ resource_name: str,
441
+ ) -> str:
442
+ """
443
+ Create a prompt with the given content and resource, then send it to the agent.
444
+
445
+ Args:
446
+ prompt_content: Either a string message or an existing PromptMessageMultipart
447
+ server_name: Name of the MCP server to retrieve the resource from
448
+ resource_name: Name or URI of the resource to retrieve
449
+
450
+ Returns:
451
+ The agent's response as a string
366
452
  """
367
- return await self.apply_prompt(prompt_name, arguments)
453
+ # Get the embedded resources
454
+ embedded_resources: List[EmbeddedResource] = await self.get_embedded_resources(
455
+ server_name, resource_name
456
+ )
457
+
458
+ # Create or update the prompt message
459
+ prompt: PromptMessageMultipart
460
+ if isinstance(prompt_content, str):
461
+ # Create a new prompt with the text and resources
462
+ content = [TextContent(type="text", text=prompt_content)]
463
+ content.extend(embedded_resources)
464
+ prompt = PromptMessageMultipart(role="user", content=content)
465
+ elif isinstance(prompt_content, PromptMessageMultipart):
466
+ # Add resources to the existing prompt
467
+ prompt = prompt_content
468
+ prompt.content.extend(embedded_resources)
469
+ else:
470
+ raise TypeError("prompt_content must be a string or PromptMessageMultipart")
471
+
472
+ # Send the prompt to the agent and return the response
473
+ return await self._llm.generate_prompt(prompt, None)
@@ -24,7 +24,6 @@ from mcp_agent.executor.executor import Executor
24
24
  from mcp_agent.executor.decorator_registry import (
25
25
  DecoratorRegistry,
26
26
  register_asyncio_decorators,
27
- register_temporal_decorators,
28
27
  )
29
28
  from mcp_agent.executor.task_registry import ActivityRegistry
30
29
  from mcp_agent.executor.executor import AsyncioExecutor
@@ -194,7 +193,6 @@ async def initialize_context(
194
193
 
195
194
  context.decorator_registry = DecoratorRegistry()
196
195
  register_asyncio_decorators(context.decorator_registry)
197
- register_temporal_decorators(context.decorator_registry)
198
196
 
199
197
  # Store the tracer in context if needed
200
198
  context.tracer = trace.get_tracer(config.otel.service_name)
@@ -2,9 +2,10 @@
2
2
  Main application wrapper for interacting with agents.
3
3
  """
4
4
 
5
- from typing import Optional, Dict, TYPE_CHECKING
5
+ from typing import Optional, Dict, Union, TYPE_CHECKING
6
6
 
7
7
  from mcp_agent.app import MCPApp
8
+ from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
8
9
  from mcp_agent.progress_display import progress_display
9
10
  from mcp_agent.workflows.orchestrator.orchestrator import Orchestrator
10
11
  from mcp_agent.workflows.parallel.parallel_llm import ParallelLLM
@@ -37,16 +38,80 @@ class AgentApp:
37
38
  # Optional: set default agent for direct calls
38
39
  self._default = next(iter(agents)) if agents else None
39
40
 
40
- async def send(self, agent_name: str, message: Optional[str]) -> str:
41
- """Core message sending"""
42
- if agent_name not in self._agents:
43
- raise ValueError(f"No agent named '{agent_name}'")
41
+ async def send_prompt(
42
+ self, prompt: PromptMessageMultipart, agent_name: Optional[str] = None
43
+ ) -> str:
44
+ """
45
+ Send a PromptMessageMultipart to an agent
46
+
47
+ Args:
48
+ prompt: The PromptMessageMultipart to send
49
+ agent_name: The name of the agent to send to (uses default if None)
50
+
51
+ Returns:
52
+ The agent's response as a string
53
+ """
54
+ target = agent_name or self._default
55
+ if not target:
56
+ raise ValueError("No default agent available")
57
+
58
+ if target not in self._agents:
59
+ raise ValueError(f"No agent named '{target}'")
60
+
61
+ proxy = self._agents[target]
62
+ return await proxy.send_prompt(prompt)
63
+
64
+ async def send(
65
+ self,
66
+ message: Union[str, PromptMessageMultipart] = None,
67
+ agent_name: Optional[str] = None,
68
+ ) -> str:
69
+ """
70
+ Send a message to the default agent or specified agent
71
+
72
+ Args:
73
+ message: Either a string message or a PromptMessageMultipart object
74
+ agent_name: The name of the agent to send to (uses default if None)
75
+
76
+ Returns:
77
+ The agent's response as a string
78
+ """
79
+ target = agent_name or self._default
80
+ if not target:
81
+ raise ValueError("No default agent available")
82
+
83
+ if target not in self._agents:
84
+ raise ValueError(f"No agent named '{target}'")
44
85
 
45
- if not message or "" == message:
46
- return await self.prompt(agent_name)
86
+ proxy = self._agents[target]
87
+ return await proxy.send(message)
88
+
89
+ async def apply_prompt(
90
+ self,
91
+ prompt_name: str,
92
+ arguments: Optional[dict[str, str]] = None,
93
+ agent_name: Optional[str] = None,
94
+ ) -> str:
95
+ """
96
+ Apply an MCP Server Prompt by name and return the assistant's response
47
97
 
48
- proxy = self._agents[agent_name]
49
- return await proxy.generate_str(message)
98
+ Args:
99
+ prompt_name: The name of the prompt to apply
100
+ arguments: Optional dictionary of string arguments to pass to the prompt template
101
+ agent_name: The name of the agent to use (uses default if None)
102
+
103
+ Returns:
104
+ The assistant's response as a string
105
+ """
106
+ target = agent_name or self._default
107
+ if not target:
108
+ raise ValueError("No default agent available")
109
+
110
+ if target not in self._agents:
111
+ raise ValueError(f"No agent named '{target}'")
112
+
113
+ proxy = self._agents[target]
114
+ return await proxy.apply_prompt(prompt_name, arguments)
50
115
 
51
116
  async def prompt(self, agent_name: Optional[str] = None, default: str = "") -> str:
52
117
  """
@@ -506,7 +571,7 @@ class AgentApp:
506
571
  if user_input == "":
507
572
  continue
508
573
 
509
- result = await self.send(agent, user_input)
574
+ result = await self.send(user_input, agent)
510
575
 
511
576
  # Check if current agent is a chain that should continue with final agent
512
577
  if agent_types.get(agent) == "Chain":
@@ -532,10 +597,21 @@ class AgentApp:
532
597
  return self._agents[name]
533
598
 
534
599
  async def __call__(
535
- self, message: Optional[str] = "", agent_name: Optional[str] = None
600
+ self,
601
+ message: Optional[Union[str, PromptMessageMultipart]] = None,
602
+ agent_name: Optional[str] = None,
536
603
  ) -> str:
537
- """Support: agent('message')"""
604
+ """
605
+ Support: agent('message') or agent(Prompt.user('message'))
606
+
607
+ Args:
608
+ message: Either a string message or a PromptMessageMultipart object
609
+ agent_name: The name of the agent to use (uses default if None)
610
+
611
+ Returns:
612
+ The agent's response as a string
613
+ """
538
614
  target = agent_name or self._default
539
615
  if not target:
540
616
  raise ValueError("No default agent available")
541
- return await self.send(target, message)
617
+ return await self.send(message, target)
@@ -172,16 +172,17 @@ async def create_agents_by_type(
172
172
  if agent_type == AgentType.BASIC:
173
173
  # Get the agent name for special handling
174
174
  agent_name = agent_data["config"].name
175
- agent = Agent(config=config, context=app_instance.context)
176
-
177
- # Set up LLM with proper configuration
178
- async with agent:
179
- llm_factory = model_factory_func(
180
- model=config.model,
181
- request_params=config.default_request_params,
182
- )
183
- agent._llm = await agent.attach_llm(llm_factory)
175
+ agent = Agent(
176
+ config=config,
177
+ context=app_instance.context,
178
+ )
179
+ await agent.initialize()
184
180
 
181
+ llm_factory = model_factory_func(
182
+ model=config.model,
183
+ request_params=config.default_request_params,
184
+ )
185
+ agent._llm = await agent.attach_llm(llm_factory)
185
186
  # Store the agent
186
187
  instance = agent
187
188
 
@@ -222,16 +223,16 @@ async def create_agents_by_type(
222
223
  default_request_params=base_params,
223
224
  )
224
225
  planner_agent = Agent(
225
- config=planner_config, context=app_instance.context
226
+ config=planner_config,
227
+ context=app_instance.context,
226
228
  )
227
229
  planner_factory = model_factory_func(
228
230
  model=config.model,
229
231
  request_params=config.default_request_params,
230
232
  )
231
233
 
232
- async with planner_agent:
233
- planner = await planner_agent.attach_llm(planner_factory)
234
-
234
+ planner = await planner_agent.attach_llm(planner_factory)
235
+ await planner.initialize()
235
236
  # Create the orchestrator with pre-configured planner
236
237
  instance = Orchestrator(
237
238
  name=config.name,
@@ -16,7 +16,6 @@ from contextlib import asynccontextmanager
16
16
  from functools import partial
17
17
 
18
18
  from mcp_agent.app import MCPApp
19
- from mcp_agent.context_dependent import ContextDependent
20
19
  from mcp_agent.config import Settings
21
20
 
22
21
  from mcp_agent.core.agent_app import AgentApp
@@ -64,13 +63,18 @@ from mcp_agent.mcp_server import AgentMCPServer
64
63
  T = TypeVar("T") # For the wrapper classes
65
64
 
66
65
 
67
- class FastAgent(ContextDependent):
66
+ class FastAgent:
68
67
  """
69
68
  A decorator-based interface for MCP Agent applications.
70
69
  Provides a simplified way to create and manage agents using decorators.
71
70
  """
72
71
 
73
- def __init__(self, name: str, config_path: Optional[str] = None):
72
+ def __init__(
73
+ self,
74
+ name: str,
75
+ config_path: Optional[str] = None,
76
+ ignore_unknown_args: bool = False,
77
+ ):
74
78
  """
75
79
  Initialize the decorator interface.
76
80
 
@@ -101,7 +105,12 @@ class FastAgent(ContextDependent):
101
105
  action="store_true",
102
106
  help="Disable progress display, tool and message logging for cleaner output",
103
107
  )
104
- self.args = parser.parse_args()
108
+
109
+ if ignore_unknown_args:
110
+ known_args, _ = parser.parse_known_args()
111
+ self.args = known_args
112
+ else:
113
+ self.args = parser.parse_args()
105
114
 
106
115
  # Quiet mode will be handled in _load_config()
107
116
 
@@ -310,6 +319,7 @@ class FastAgent(ContextDependent):
310
319
  """
311
320
  active_agents = {}
312
321
  had_error = False
322
+ await self.app.initialize()
313
323
 
314
324
  # Handle quiet mode by disabling logger settings after initialization
315
325
  quiet_mode = hasattr(self, "args") and self.args.quiet
@@ -372,7 +382,7 @@ class FastAgent(ContextDependent):
372
382
 
373
383
  # Create wrapper with all agents
374
384
  wrapper = AgentApp(agent_app, active_agents)
375
-
385
+
376
386
  # Store reference to AgentApp in MCPApp for proxies to access
377
387
  agent_app._agent_app = wrapper
378
388