fast-agent-mcp 0.2.43__py3-none-any.whl → 0.2.44__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fast-agent-mcp might be problematic. Click here for more details.

Files changed (30) hide show
  1. {fast_agent_mcp-0.2.43.dist-info → fast_agent_mcp-0.2.44.dist-info}/METADATA +3 -2
  2. {fast_agent_mcp-0.2.43.dist-info → fast_agent_mcp-0.2.44.dist-info}/RECORD +30 -29
  3. mcp_agent/agents/base_agent.py +60 -22
  4. mcp_agent/config.py +2 -0
  5. mcp_agent/core/agent_app.py +15 -5
  6. mcp_agent/core/enhanced_prompt.py +81 -11
  7. mcp_agent/core/fastagent.py +9 -1
  8. mcp_agent/core/interactive_prompt.py +60 -1
  9. mcp_agent/core/usage_display.py +10 -3
  10. mcp_agent/llm/augmented_llm.py +4 -5
  11. mcp_agent/llm/augmented_llm_passthrough.py +15 -0
  12. mcp_agent/llm/providers/augmented_llm_anthropic.py +4 -3
  13. mcp_agent/llm/providers/augmented_llm_bedrock.py +3 -3
  14. mcp_agent/llm/providers/augmented_llm_google_native.py +4 -7
  15. mcp_agent/llm/providers/augmented_llm_openai.py +5 -8
  16. mcp_agent/llm/providers/augmented_llm_tensorzero.py +6 -7
  17. mcp_agent/llm/providers/google_converter.py +6 -9
  18. mcp_agent/llm/providers/multipart_converter_anthropic.py +5 -4
  19. mcp_agent/llm/providers/multipart_converter_openai.py +33 -0
  20. mcp_agent/llm/providers/multipart_converter_tensorzero.py +3 -2
  21. mcp_agent/logging/rich_progress.py +6 -2
  22. mcp_agent/logging/transport.py +30 -36
  23. mcp_agent/mcp/helpers/content_helpers.py +26 -11
  24. mcp_agent/mcp/interfaces.py +22 -2
  25. mcp_agent/mcp/prompt_message_multipart.py +2 -3
  26. mcp_agent/ui/console_display.py +353 -142
  27. mcp_agent/ui/console_display_legacy.py +401 -0
  28. {fast_agent_mcp-0.2.43.dist-info → fast_agent_mcp-0.2.44.dist-info}/WHEEL +0 -0
  29. {fast_agent_mcp-0.2.43.dist-info → fast_agent_mcp-0.2.44.dist-info}/entry_points.txt +0 -0
  30. {fast_agent_mcp-0.2.43.dist-info → fast_agent_mcp-0.2.44.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.43
3
+ Version: 0.2.44
4
4
  Summary: Define, Prompt and Test MCP enabled Agents and Workflows
5
5
  Author-email: Shaun Smith <fastagent@llmindset.co.uk>
6
6
  License: Apache License
@@ -218,7 +218,7 @@ Requires-Dist: deprecated>=1.2.18
218
218
  Requires-Dist: email-validator>=2.2.0
219
219
  Requires-Dist: fastapi>=0.115.6
220
220
  Requires-Dist: google-genai
221
- Requires-Dist: mcp==1.10.1
221
+ Requires-Dist: mcp==1.12.0
222
222
  Requires-Dist: openai>=1.93.0
223
223
  Requires-Dist: opentelemetry-distro>=0.50b0
224
224
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
@@ -229,6 +229,7 @@ Requires-Dist: opentelemetry-instrumentation-openai>=0.40.14; python_version >=
229
229
  Requires-Dist: prompt-toolkit>=3.0.50
230
230
  Requires-Dist: pydantic-settings>=2.7.0
231
231
  Requires-Dist: pydantic>=2.10.4
232
+ Requires-Dist: pyperclip>=1.9.0
232
233
  Requires-Dist: pyyaml>=6.0.2
233
234
  Requires-Dist: rich>=13.9.4
234
235
  Requires-Dist: tensorzero>=2025.6.3
@@ -1,6 +1,6 @@
1
1
  mcp_agent/__init__.py,sha256=18T0AG0W9sJhTY38O9GFFOzliDhxx9p87CvRyti9zbw,1620
2
2
  mcp_agent/app.py,sha256=3mtHP1nRQcRaKhhxgTmCOv00alh70nT7UxNA8bN47QE,5560
3
- mcp_agent/config.py,sha256=ORid5f2YSkkNHIWHFgIWdcqyqr3g1TGV5ZTQMinuMi0,18869
3
+ mcp_agent/config.py,sha256=RjwgvR-Sys4JIzhNyEsaS_NarCe157RenJLOsioUtDk,18980
4
4
  mcp_agent/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
5
5
  mcp_agent/context.py,sha256=9s1F1-UfcI8rz9Yxm6EXHZ4cInuE_cOl_HFu8N8k3yc,7497
6
6
  mcp_agent/context_dependent.py,sha256=QXfhw3RaQCKfscEEBRGuZ3sdMWqkgShz2jJ1ivGGX1I,1455
@@ -9,7 +9,7 @@ mcp_agent/mcp_server_registry.py,sha256=lmz-aES-l7Gbg4itDF0iCmpso_KD8bVazVKSVzjw
9
9
  mcp_agent/progress_display.py,sha256=GeJU9VUt6qKsFVymG688hCMVCsAygG9ifiiEb5IcbN4,361
10
10
  mcp_agent/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  mcp_agent/agents/agent.py,sha256=EAYlcP1qqI1D0_CS808I806z1048FBjZQxxpcCZPeIU,3154
12
- mcp_agent/agents/base_agent.py,sha256=EpdwZKktelEVdQUYyMoohtVwGgwas-rdM9r1nuMQIQk,30597
12
+ mcp_agent/agents/base_agent.py,sha256=VCBWJ-l1zMQiBuONGzqcbqPUQfXK4oq-pBB5lJrMgQ0,32318
13
13
  mcp_agent/agents/workflow/__init__.py,sha256=HloteEW6kalvgR0XewpiFAqaQlMPlPJYg5p3K33IUzI,25
14
14
  mcp_agent/agents/workflow/chain_agent.py,sha256=eIlImirrSXkqBJmPuAJgOKis81Cl6lZEGM0-6IyaUV8,6105
15
15
  mcp_agent/agents/workflow/evaluator_optimizer.py,sha256=ysUMGM2NzeCIutgr_vXH6kUPpZMw0cX4J_Wl1r8eT84,13296
@@ -30,19 +30,19 @@ mcp_agent/cli/commands/server_helpers.py,sha256=x5tD_qhf1W4D2li09sfOyfRWCOCa6lmp
30
30
  mcp_agent/cli/commands/setup.py,sha256=eOEd4TL-b0DaDeSJMGOfNOsTEItoZ67W88eTP4aP-bo,6482
31
31
  mcp_agent/cli/commands/url_parser.py,sha256=5VdtcHRHzi67YignStVbz7u-rcvNNErw9oJLAUFOtEY,5855
32
32
  mcp_agent/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- mcp_agent/core/agent_app.py,sha256=mMWfScEylf1l-rKzmRdoA7WIIBRvSypfZONDBYdo1M8,15919
33
+ mcp_agent/core/agent_app.py,sha256=SolGwejEmv9XtsTsmiMkNKPia7RN1VcHXm6JoEo4hvQ,16187
34
34
  mcp_agent/core/agent_types.py,sha256=7zVzAFWjvh5dDV3TuDwmO9LAWmDjYnZd3eeLH-wvvIQ,1705
35
35
  mcp_agent/core/direct_decorators.py,sha256=sYoEA1EmdyAxTpQwUDUjQYWY73VviM-fBnV1Zv7KfeU,19047
36
36
  mcp_agent/core/direct_factory.py,sha256=d_HvbAxyv2WrM07zyCpLXFVn7eArXk1LZmLKS49hzJo,19537
37
- mcp_agent/core/enhanced_prompt.py,sha256=jrAINowXPqXWGrk_g6xcvMXFE0SEBetNdDtV25vnCBU,33411
37
+ mcp_agent/core/enhanced_prompt.py,sha256=e3FA0_70kw4HRxXCYQs5sO0qzvsM47pc6UG186okXtk,36324
38
38
  mcp_agent/core/error_handling.py,sha256=xoyS2kLe0eG0bj2eSJCJ2odIhGUve2SbDR7jP-A-uRw,624
39
39
  mcp_agent/core/exceptions.py,sha256=ENAD_qGG67foxy6vDkIvc-lgopIUQy6O7zvNPpPXaQg,2289
40
- mcp_agent/core/fastagent.py,sha256=tAxapB3sjNyK6FqsJdOZt-IN5uYAi8DL1B9RHcGu55g,24849
41
- mcp_agent/core/interactive_prompt.py,sha256=1XXtX8HnBt04hqfkCjPiVQP4OZegfuDa6hEQEwCUQRY,30493
40
+ mcp_agent/core/fastagent.py,sha256=qA64fwmJ6TVFEvmj6l-oTWPD28Js5zJvdDnPjH-agzQ,25117
41
+ mcp_agent/core/interactive_prompt.py,sha256=Gpwn7v7m3nw7fR_W7bs5XYArrny_xJK06DOURUwpzI4,32756
42
42
  mcp_agent/core/mcp_content.py,sha256=2D7KHY9mG_vxoDwFLKvsPQV9VRIzHItM7V-jcEnACh8,8878
43
43
  mcp_agent/core/prompt.py,sha256=qnintOUGEoDPYLI9bu9G2OlgVMCe5ZPUZilgMzydXhc,7919
44
44
  mcp_agent/core/request_params.py,sha256=qmFWZXeYEJyYw2IwonyrTnZWxQG7qX6bKpOPcqETa60,1603
45
- mcp_agent/core/usage_display.py,sha256=VeVhlNRoTH109Yv3tokfWUKgxD4s_a2cFuvoNUbVEGU,7338
45
+ mcp_agent/core/usage_display.py,sha256=CcCQbTm5ftMgkoBgr5NWzHmYFBK5cSU-FM8yiBOVzGA,7527
46
46
  mcp_agent/core/validation.py,sha256=8D6d3mQanvzC2dXx5yc8-5bkoWEh9cxuT6-YSthSGFk,12676
47
47
  mcp_agent/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  mcp_agent/executor/executor.py,sha256=E44p6d-o3OMRoP_dNs_cDnyti91LQ3P9eNU88mSi1kc,9462
@@ -56,8 +56,8 @@ mcp_agent/human_input/elicitation_state.py,sha256=Unl9uhEybUqACCUimnETdfUprJNpYD
56
56
  mcp_agent/human_input/handler.py,sha256=s712Z5ssTCwjL9-VKoIdP5CtgMh43YvepynYisiWTTA,3144
57
57
  mcp_agent/human_input/types.py,sha256=RtWBOVzy8vnYoQrc36jRLn8z8N3C4pDPMBN5vF6qM5Y,1476
58
58
  mcp_agent/llm/__init__.py,sha256=d8zgwG-bRFuwiMNMYkywg_qytk4P8lawyld_meuUmHI,68
59
- mcp_agent/llm/augmented_llm.py,sha256=QMrNcyP-D5yfdUEhuHKtSDDg-_YnYaw8krGbafu0QTI,27567
60
- mcp_agent/llm/augmented_llm_passthrough.py,sha256=F8KifmTwoQ7zyncjmoRek8SBfGdgc9yc5LRXwMQH-bg,8640
59
+ mcp_agent/llm/augmented_llm.py,sha256=FwH3nFwtqX9JJiwsHWvBCwDRooAMUhVM258-rUMheRI,27568
60
+ mcp_agent/llm/augmented_llm_passthrough.py,sha256=-Pu_cW5p7gKyc6E7OT7lG642RyAFkv-uj6U-JwKpOPE,9421
61
61
  mcp_agent/llm/augmented_llm_playback.py,sha256=BQeBXRpO-xGAY9wIJxyde6xpHmZEdQPLd32frF8t3QQ,4916
62
62
  mcp_agent/llm/augmented_llm_silent.py,sha256=IUnK_1Byy4D9TG0Pj46LFeNezgSTQ8d6MQIHWAImBwE,1846
63
63
  mcp_agent/llm/augmented_llm_slow.py,sha256=DDSD8bL2flmQrVHZm-UDs7sR8aHRWkDOcOW-mX_GPok,2067
@@ -73,21 +73,21 @@ mcp_agent/llm/usage_tracking.py,sha256=rF6v8QQDam8QbvlP4jzHljKqvuNHExeYDLkUMI86c
73
73
  mcp_agent/llm/providers/__init__.py,sha256=heVxtmuqFJOnjjxHz4bWSqTAxXoN1E8twC_gQ_yJpHk,265
74
74
  mcp_agent/llm/providers/anthropic_utils.py,sha256=vYDN5G5jKMhD2CQg8veJYab7tvvzYkDMq8M1g_hUAQg,3275
75
75
  mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=XylkJKZ9theSVUxJKOZkf1244hgzng4Ng4Dr209Qb-w,1101
76
- mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=dKXP8d36jzqThV8E404PUYbTuQbRz9x7uQScW4_BU6U,24060
76
+ mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=kmzJ_45eMerUkGZ7Mzy544SLpxcUbfOnAr0h_mHktcs,23980
77
77
  mcp_agent/llm/providers/augmented_llm_azure.py,sha256=sBVWgY88F4OsdRSHl71BAT2p3XPvuZp844z1ubwcV7U,6098
78
- mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=tcbMovzA4W1JMB-PrvxXlwea8if-tmYooq9ME2W6Leo,82327
78
+ mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=nfby1udL07zPTOLlN_tFxd1h0JRioo2oIW7v4iP4Bnk,82267
79
79
  mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=zI9a90dwT4r6E1f_xp4K50Cj9sD7y7kNRgjo0s1pd5w,3804
80
80
  mcp_agent/llm/providers/augmented_llm_generic.py,sha256=5Uq8ZBhcFuQTt7koP_5ykolREh2iWu8zKhNbh3pM9lQ,1210
81
- mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=meWvjiNny2T8Map_TuLl8gx9JX8Ly8orHMFUCx3gtFU,22389
81
+ mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=c6zczfs-Iw70j3OYELHJ4S7CRwAddkeXinex_yLMhmU,22194
82
82
  mcp_agent/llm/providers/augmented_llm_google_oai.py,sha256=cO4dvjTl9ymqEurCOo5nP09ATfXVjgkuk1yZAlWpS1s,1137
83
- mcp_agent/llm/providers/augmented_llm_openai.py,sha256=AP2ZXZhFXntZlhm50Bi2QwLfTybIX134Y6e_OktdhG8,24321
83
+ mcp_agent/llm/providers/augmented_llm_openai.py,sha256=cxctddW9a-5Kv3yGSMBudQh_L7pc9yV5fEOhT7J8ho0,24169
84
84
  mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=V_TlVKm92GHBxYIo6gpvH_6cAaIdppS25Tz6x5T7LW0,2341
85
- mcp_agent/llm/providers/augmented_llm_tensorzero.py,sha256=Mol_Wzj_ZtccW-LMw0oFwWUt1m1yfofloay9QYNP23c,20729
85
+ mcp_agent/llm/providers/augmented_llm_tensorzero.py,sha256=z4PtjW_TS6xBVQl-0nRqegvRdVZFQiRMfWYBSMEWkdY,20577
86
86
  mcp_agent/llm/providers/augmented_llm_xai.py,sha256=fJiO9Vkgi32pEMijxMbqoKrPCCNJmR_3YEnX0UCqOVs,1332
87
- mcp_agent/llm/providers/google_converter.py,sha256=zsqxJJ636WzCL2K6w-yB94O8bdNR6mo8f5mQEnUJFyg,16831
88
- mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=t5lHYGfFUacJldnrVtMNW-8gEMoto8Y7hJkDrnyZR-Y,16650
89
- mcp_agent/llm/providers/multipart_converter_openai.py,sha256=kCvtTFOcOejg2BVI3_-F9OCFxAoShSj2i0hdCajHCIw,15955
90
- mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=BFTdyVk42HZskDAuTHicfDTUJq89d1fz8C9nAOuHxlE,8646
87
+ mcp_agent/llm/providers/google_converter.py,sha256=xCUVw4W7lqBvJMgSKKdzW4Y00zmHBgCR6pOoWLYQQfw,16699
88
+ mcp_agent/llm/providers/multipart_converter_anthropic.py,sha256=QsgIwWJ14SNZsun3fKDQaUx5AYdk8X6UYeBgYlZgZN0,16607
89
+ mcp_agent/llm/providers/multipart_converter_openai.py,sha256=1zHlkMKY-16RL8qnrx7kI53IHmCiqASNvYsAdofSq_I,17000
90
+ mcp_agent/llm/providers/multipart_converter_tensorzero.py,sha256=Tr3DgogthxqTw04ajblwE8aB3Ft42X7aSXsMlm5FP4k,8619
91
91
  mcp_agent/llm/providers/openai_multipart.py,sha256=qKBn7d3jSabnJmVgWweVzqh8q9mBqr09fsPmP92niAQ,6899
92
92
  mcp_agent/llm/providers/openai_utils.py,sha256=T4bTCL9f7DsoS_zoKgQKv_FUv_4n98vgbvaUpdWZJr8,1875
93
93
  mcp_agent/llm/providers/sampling_converter_anthropic.py,sha256=35WzBWkPklnuMlu5S6XsQIq0YL58NOy8Ja6A_l4m6eM,1612
@@ -97,27 +97,27 @@ mcp_agent/logging/events.py,sha256=dSJJfuCd59-ZyYTVcf0M4HQd6iXb5k50PSAeoq1CpH0,4
97
97
  mcp_agent/logging/json_serializer.py,sha256=qkfxnR9ka6OgvwSpM2CggELbEtzzkApm0s_KYz11RDY,5791
98
98
  mcp_agent/logging/listeners.py,sha256=_S4Jp5_KWp0kUfrx4BxDdNCeQK3MNT3Zi9AaolPri7A,6648
99
99
  mcp_agent/logging/logger.py,sha256=v2_D5kWLSS9u4ueSU7q6cWF1oSmTVeAAtgnwR0LrbXI,11056
100
- mcp_agent/logging/rich_progress.py,sha256=NQbW010VxfzgJw8BRaqKVTIFlTNvDfmMcoOt7pxGvzQ,5362
101
- mcp_agent/logging/transport.py,sha256=m8YsLLu5T8eof_ndpLQs4gHOzqqEL98xsVwBwDsBfxI,17335
100
+ mcp_agent/logging/rich_progress.py,sha256=uMAKDPO8TlhT7uTeJzOEwQPme8pu8qCADLNbsI1vV8g,5544
101
+ mcp_agent/logging/transport.py,sha256=_RVckOdcs_mXv6Jwz-MPe0vVTQEKsbejHdteyK5hBQA,16960
102
102
  mcp_agent/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  mcp_agent/mcp/common.py,sha256=MpSC0fLO21RcDz4VApah4C8_LisVGz7OXkR17Xw-9mY,431
104
104
  mcp_agent/mcp/elicitation_factory.py,sha256=gY0gEsF8Jdg01nSsrVbbl62ZS1A725QgDRB6UDPCadc,3162
105
105
  mcp_agent/mcp/elicitation_handlers.py,sha256=w2S4kBn05pIKdq2-X13MErinFg5jSElwFsoTuW3zFSs,6618
106
106
  mcp_agent/mcp/gen_client.py,sha256=fAVwFVCgSamw4PwoWOV4wrK9TABx1S_zZv8BctRyF2k,3030
107
107
  mcp_agent/mcp/hf_auth.py,sha256=7szw4rkwRyK3J-sUTcVZHdwoLIZqlYo8XolJnZdjOww,4571
108
- mcp_agent/mcp/interfaces.py,sha256=NxUDi4eI-qWfaOS1QHWr3EjAweV-CX_CBJeBCwTwr7g,7102
108
+ mcp_agent/mcp/interfaces.py,sha256=Zrb-O-TuExlWJxuP0bIN8ZV0UpIoz5Rw7x1Lj-BsbHc,7717
109
109
  mcp_agent/mcp/logger_textio.py,sha256=vljC1BtNTCxBAda9ExqNB-FwVNUZIuJT3h1nWmCjMws,3172
110
110
  mcp_agent/mcp/mcp_agent_client_session.py,sha256=nEHrSalG5z47BKGwE9ooOmlSTc4Gb7qdEut071Dwepo,8987
111
111
  mcp_agent/mcp/mcp_aggregator.py,sha256=D1xFBVVq_4Tn1Ka16SZTVB3qeU-FO5501ITHGXTuXs0,49730
112
112
  mcp_agent/mcp/mcp_connection_manager.py,sha256=dJxjnv2IRzlFIxrbPFl39-pmGcZHgyeMXVlMfqpREhE,17974
113
113
  mcp_agent/mcp/mime_utils.py,sha256=difepNR_gpb4MpMLkBRAoyhDk-AjXUHTiqKvT_VwS1o,1805
114
- mcp_agent/mcp/prompt_message_multipart.py,sha256=BDwRdNwyWHb2q2bccDb2iR2VlORqVvkvoG3xYzcMpCE,4403
114
+ mcp_agent/mcp/prompt_message_multipart.py,sha256=XDlFODtOIepespQ23hvh37i3GF2L9Hju4AdNHijwe9k,4350
115
115
  mcp_agent/mcp/prompt_render.py,sha256=k3v4BZDThGE2gGiOYVQtA6x8WTEdOuXIEnRafANhN1U,2996
116
116
  mcp_agent/mcp/prompt_serialization.py,sha256=MQY6QxnhQTiq0oBDsyRzFtX8sBiovUjzUFX78As8q60,17974
117
117
  mcp_agent/mcp/resource_utils.py,sha256=K4XY8bihmBMleRTZ2viMPiD2Y2HWxFnlgIJi6dd_PYE,6588
118
118
  mcp_agent/mcp/sampling.py,sha256=PpUtLDvu9K3U8445z6m_esHeKstdSr-JBTyn9d8ppJM,6665
119
119
  mcp_agent/mcp/helpers/__init__.py,sha256=sKqwlUR3jSsd9PVJKjXtxHgZA1YOdzPtsSW4xVey77Q,52
120
- mcp_agent/mcp/helpers/content_helpers.py,sha256=fOrRq6sIHR0Zn18k9GRRn9PWBB5WosPLhvK0yVXg2Vg,4191
120
+ mcp_agent/mcp/helpers/content_helpers.py,sha256=_P5xfVpJg4F7lBM-v6-1Bjtvfgr9UfTQoW2FSxyxil4,4112
121
121
  mcp_agent/mcp/helpers/server_config_helpers.py,sha256=MkyZB2ZzfsBNsqyGd0LfUOoXxhAMS28VF-f747cJJpY,978
122
122
  mcp_agent/mcp/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  mcp_agent/mcp/prompts/__main__.py,sha256=gr1Tdz9fcK0EXjEuZg_BOnKUmvhYq5AH2lFZicVyNb0,237
@@ -160,9 +160,10 @@ mcp_agent/resources/examples/workflows/router.py,sha256=56FX7JhZ6ERafWGoVhspoalT
160
160
  mcp_agent/resources/examples/workflows/short_story.md,sha256=XN9I2kzCcMmke3dE5F2lyRH5iFUZUQ8Sy-hS3rm_Wlc,1153
161
161
  mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKvucJtDgAFIJfnlbsbGZO5bBWu0,1187
162
162
  mcp_agent/tools/tool_definition.py,sha256=L3Pxl-uLEXqlVoo-bYuFTFALeI-2pIU44YgFhsTKEtM,398
163
- mcp_agent/ui/console_display.py,sha256=U9ZWzeu3dUGNCDcyFVSTqX_rpxXbn3uNmuvJ4SIlzi0,15730
164
- fast_agent_mcp-0.2.43.dist-info/METADATA,sha256=GzA8s5uVpEhN0t0iJD4E7Qy0SyvDfkrl1K5LYRellzg,31012
165
- fast_agent_mcp-0.2.43.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
166
- fast_agent_mcp-0.2.43.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
167
- fast_agent_mcp-0.2.43.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
168
- fast_agent_mcp-0.2.43.dist-info/RECORD,,
163
+ mcp_agent/ui/console_display.py,sha256=2G8hv4Ig70IHCHvw7FK-ksDcp9UHqbUYU-Y64_j0Nuk,25826
164
+ mcp_agent/ui/console_display_legacy.py,sha256=sm2v61-IPVafbF7uUaOyhO2tW_zgFWOjNS83IEWqGgI,14931
165
+ fast_agent_mcp-0.2.44.dist-info/METADATA,sha256=lvZvAbFvs2tbNpHi35Cbh_PgeyNtWFTnI8Fa8RHpXyQ,31044
166
+ fast_agent_mcp-0.2.44.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
167
+ fast_agent_mcp-0.2.44.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
168
+ fast_agent_mcp-0.2.44.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
169
+ fast_agent_mcp-0.2.44.dist-info/RECORD,,
@@ -330,12 +330,12 @@ class BaseAgent(MCPAggregator, AgentProtocol):
330
330
  def _matches_pattern(self, name: str, pattern: str, server_name: str) -> bool:
331
331
  """
332
332
  Check if a name matches a pattern for a specific server.
333
-
333
+
334
334
  Args:
335
335
  name: The name to match (could be tool name, resource URI, or prompt name)
336
336
  pattern: The pattern to match against (e.g., "add", "math*", "resource://math/*")
337
337
  server_name: The server name (used for tool name prefixing)
338
-
338
+
339
339
  Returns:
340
340
  True if the name matches the pattern
341
341
  """
@@ -343,7 +343,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
343
343
  if name.startswith(f"{server_name}-"):
344
344
  full_pattern = f"{server_name}-{pattern}"
345
345
  return fnmatch.fnmatch(name, full_pattern)
346
-
346
+
347
347
  # For resources and prompts, match directly against the pattern
348
348
  return fnmatch.fnmatch(name, pattern)
349
349
 
@@ -365,9 +365,9 @@ class BaseAgent(MCPAggregator, AgentProtocol):
365
365
  filtered_tools = []
366
366
  for tool in result.tools:
367
367
  # Extract server name from tool name (e.g., "mathematics-add" -> "mathematics")
368
- if '-' in tool.name:
369
- server_name = tool.name.split('-', 1)[0]
370
-
368
+ if "-" in tool.name:
369
+ server_name = tool.name.split("-", 1)[0]
370
+
371
371
  # Check if this server has tool filters
372
372
  if server_name in self.config.tools:
373
373
  # Check if tool matches any pattern for this server
@@ -495,48 +495,70 @@ class BaseAgent(MCPAggregator, AgentProtocol):
495
495
 
496
496
  async def apply_prompt(
497
497
  self,
498
- prompt_name: str,
498
+ prompt: Union[str, GetPromptResult],
499
499
  arguments: Dict[str, str] | None = None,
500
500
  agent_name: str | None = None,
501
501
  server_name: str | None = None,
502
+ as_template: bool = False,
502
503
  ) -> str:
503
504
  """
504
- Apply an MCP Server Prompt by name and return the assistant's response.
505
+ Apply an MCP Server Prompt by name or GetPromptResult and return the assistant's response.
505
506
  Will search all available servers for the prompt if not namespaced and no server_name provided.
506
507
 
507
508
  If the last message in the prompt is from a user, this will automatically
508
509
  generate an assistant response to ensure we always end with an assistant message.
509
510
 
510
511
  Args:
511
- prompt_name: The name of the prompt to apply
512
+ prompt: The name of the prompt to apply OR a GetPromptResult object
512
513
  arguments: Optional dictionary of string arguments to pass to the prompt template
513
514
  agent_name: Optional agent name (ignored at this level, used by multi-agent apps)
514
515
  server_name: Optional name of the server to get the prompt from
516
+ as_template: If True, store as persistent template (always included in context)
515
517
 
516
518
  Returns:
517
519
  The assistant's response or error message
518
520
  """
519
521
 
520
- # Get the prompt - this will search all servers if needed
521
- self.logger.debug(f"Loading prompt '{prompt_name}'")
522
- prompt_result: GetPromptResult = await self.get_prompt(prompt_name, arguments, server_name)
522
+ # Handle both string and GetPromptResult inputs
523
+ if isinstance(prompt, str):
524
+ prompt_name = prompt
525
+ # Get the prompt - this will search all servers if needed
526
+ self.logger.debug(f"Loading prompt '{prompt_name}'")
527
+ prompt_result: GetPromptResult = await self.get_prompt(
528
+ prompt_name, arguments, server_name
529
+ )
530
+
531
+ if not prompt_result or not prompt_result.messages:
532
+ error_msg = f"Prompt '{prompt_name}' could not be found or contains no messages"
533
+ self.logger.warning(error_msg)
534
+ return error_msg
523
535
 
524
- if not prompt_result or not prompt_result.messages:
525
- error_msg = f"Prompt '{prompt_name}' could not be found or contains no messages"
526
- self.logger.warning(error_msg)
527
- return error_msg
536
+ # Get the display name (namespaced version)
537
+ namespaced_name = getattr(prompt_result, "namespaced_name", prompt_name)
538
+ else:
539
+ # prompt is a GetPromptResult object
540
+ prompt_result = prompt
541
+ if not prompt_result or not prompt_result.messages:
542
+ error_msg = "Provided GetPromptResult contains no messages"
543
+ self.logger.warning(error_msg)
544
+ return error_msg
545
+
546
+ # Use a reasonable display name
547
+ namespaced_name = getattr(prompt_result, "namespaced_name", "provided_prompt")
528
548
 
529
- # Get the display name (namespaced version)
530
- namespaced_name = getattr(prompt_result, "namespaced_name", prompt_name)
531
549
  self.logger.debug(f"Using prompt '{namespaced_name}'")
532
550
 
533
551
  # Convert prompt messages to multipart format using the safer method
534
552
  multipart_messages = PromptMessageMultipart.from_get_prompt_result(prompt_result)
535
553
 
536
- # Always call generate to ensure LLM implementations can handle prompt templates
537
- # This is critical for stateful LLMs like PlaybackLLM
538
- response = await self.generate(multipart_messages, None)
539
- return response.first_text()
554
+ if as_template:
555
+ # Use apply_prompt_template to store as persistent prompt messages
556
+ return await self.apply_prompt_template(prompt_result, namespaced_name)
557
+ else:
558
+ # Always call generate to ensure LLM implementations can handle prompt templates
559
+ # This is critical for stateful LLMs like PlaybackLLM
560
+ response = await self.generate(multipart_messages, None)
561
+ return response.first_text()
540
562
 
541
563
  async def get_embedded_resources(
542
564
  self, resource_uri: str, server_name: str | None = None
@@ -636,6 +658,22 @@ class BaseAgent(MCPAggregator, AgentProtocol):
636
658
  with self.tracer.start_as_current_span(f"Agent: '{self.name}' generate"):
637
659
  return await self._llm.generate(multipart_messages, request_params)
638
660
 
661
+ async def apply_prompt_template(self, prompt_result: GetPromptResult, prompt_name: str) -> str:
662
+ """
663
+ Apply a prompt template as persistent context that will be included in all future conversations.
664
+ Delegates to the attached LLM.
665
+
666
+ Args:
667
+ prompt_result: The GetPromptResult containing prompt messages
668
+ prompt_name: The name of the prompt being applied
669
+
670
+ Returns:
671
+ String representation of the assistant's response if generated
672
+ """
673
+ assert self._llm
674
+ with self.tracer.start_as_current_span(f"Agent: '{self.name}' apply_prompt_template"):
675
+ return await self._llm.apply_prompt_template(prompt_result, prompt_name)
676
+
639
677
  async def structured(
640
678
  self,
641
679
  multipart_messages: List[PromptMessageMultipart],
mcp_agent/config.py CHANGED
@@ -319,6 +319,8 @@ class LoggerSettings(BaseModel):
319
319
  """Truncate display of long tool calls"""
320
320
  enable_markup: bool = True
321
321
  """Enable markup in console output. Disable for outputs that may conflict with rich console formatting"""
322
+ use_legacy_display: bool = False
323
+ """Use the legacy console display instead of the new style display"""
322
324
 
323
325
 
324
326
  def find_fastagent_config_files(start_path: Path) -> Tuple[Optional[Path], Optional[Path]]:
@@ -5,7 +5,7 @@ Direct AgentApp implementation for interacting with agents without proxies.
5
5
  from typing import Dict, List, Optional, Union
6
6
 
7
7
  from deprecated import deprecated
8
- from mcp.types import PromptMessage
8
+ from mcp.types import GetPromptResult, PromptMessage
9
9
  from rich import print as rich_print
10
10
 
11
11
  from mcp_agent.agents.agent import Agent
@@ -108,22 +108,26 @@ class AgentApp:
108
108
 
109
109
  async def apply_prompt(
110
110
  self,
111
- prompt_name: str,
111
+ prompt: Union[str, GetPromptResult],
112
112
  arguments: Dict[str, str] | None = None,
113
113
  agent_name: str | None = None,
114
+ as_template: bool = False,
114
115
  ) -> str:
115
116
  """
116
117
  Apply a prompt template to an agent (default agent if not specified).
117
118
 
118
119
  Args:
119
- prompt_name: Name of the prompt template to apply
120
+ prompt: Name of the prompt template to apply OR a GetPromptResult object
120
121
  arguments: Optional arguments for the prompt template
121
122
  agent_name: Name of the agent to send to
123
+ as_template: If True, store as persistent template (always included in context)
122
124
 
123
125
  Returns:
124
126
  The agent's response as a string
125
127
  """
126
- return await self._agent(agent_name).apply_prompt(prompt_name, arguments)
128
+ return await self._agent(agent_name).apply_prompt(
129
+ prompt, arguments, as_template=as_template
130
+ )
127
131
 
128
132
  async def list_prompts(self, server_name: str | None = None, agent_name: str | None = None):
129
133
  """
@@ -235,7 +239,12 @@ class AgentApp:
235
239
  """
236
240
  return await self.interactive(agent_name=agent_name, default_prompt=default_prompt)
237
241
 
238
- async def interactive(self, agent_name: str | None = None, default_prompt: str = "", pretty_print_parallel: bool = False) -> str:
242
+ async def interactive(
243
+ self,
244
+ agent_name: str | None = None,
245
+ default_prompt: str = "",
246
+ pretty_print_parallel: bool = False,
247
+ ) -> str:
239
248
  """
240
249
  Interactive prompt for sending messages with advanced features.
241
250
 
@@ -283,6 +292,7 @@ class AgentApp:
283
292
  agent = self._agents.get(agent_name)
284
293
  if agent and agent.agent_type == AgentType.PARALLEL:
285
294
  from mcp_agent.ui.console_display import ConsoleDisplay
295
+
286
296
  display = ConsoleDisplay(config=None)
287
297
  display.show_parallel_results(agent)
288
298
 
@@ -106,15 +106,35 @@ async def _display_agent_info_helper(agent_name: str, agent_provider: object) ->
106
106
  else:
107
107
  # For regular agents, only display if they have MCP servers attached
108
108
  if server_count > 0:
109
- # Pluralization helpers
109
+ # Build display parts in order: tools, prompts, resources (omit if count is 0)
110
+ display_parts = []
111
+
112
+ if tool_count > 0:
113
+ tool_word = "tool" if tool_count == 1 else "tools"
114
+ display_parts.append(f"{tool_count:,}[dim] {tool_word}[/dim]")
115
+
116
+ if prompt_count > 0:
117
+ prompt_word = "prompt" if prompt_count == 1 else "prompts"
118
+ display_parts.append(f"{prompt_count:,}[dim] {prompt_word}[/dim]")
119
+
120
+ if resource_count > 0:
121
+ resource_word = "resource" if resource_count == 1 else "resources"
122
+ display_parts.append(f"{resource_count:,}[dim] {resource_word}[/dim]")
123
+
124
+ # Always show server count
110
125
  server_word = "Server" if server_count == 1 else "Servers"
111
- tool_word = "tool" if tool_count == 1 else "tools"
112
- resource_word = "resource" if resource_count == 1 else "resources"
113
- prompt_word = "prompt" if prompt_count == 1 else "prompts"
126
+ server_text = f"{server_count:,}[dim] MCP {server_word}[/dim]"
114
127
 
115
- rich_print(
116
- f"[dim]Agent [/dim][blue]{agent_name}[/blue][dim]:[/dim] {server_count:,}[dim] MCP {server_word}, [/dim]{tool_count:,}[dim] {tool_word}, [/dim]{resource_count:,}[dim] {resource_word}, [/dim]{prompt_count:,}[dim] {prompt_word} available[/dim]"
117
- )
128
+ if display_parts:
129
+ content = (
130
+ f"{server_text}[dim], [/dim]"
131
+ + "[dim], [/dim]".join(display_parts)
132
+ + "[dim] available[/dim]"
133
+ )
134
+ else:
135
+ content = f"{server_text}[dim] available[/dim]"
136
+
137
+ rich_print(f"[dim]Agent [/dim][blue]{agent_name}[/blue][dim]:[/dim] {content}")
118
138
 
119
139
  # Mark as shown
120
140
  _agent_info_shown.add(agent_name)
@@ -274,6 +294,7 @@ class AgentCompleter(Completer):
274
294
  "prompt": "List and select MCP prompts, or apply specific prompt (/prompt <name>)",
275
295
  "agents": "List available agents",
276
296
  "usage": "Show current usage statistics",
297
+ "markdown": "Show last assistant message without markdown formatting",
277
298
  "help": "Show available commands",
278
299
  "clear": "Clear the screen",
279
300
  "STOP": "Stop this prompting session and move to next workflow step",
@@ -398,7 +419,7 @@ def get_text_from_editor(initial_text: str = "") -> str:
398
419
  return edited_text.strip() # Added strip() to remove trailing newlines often added by editors
399
420
 
400
421
 
401
- def create_keybindings(on_toggle_multiline=None, app=None):
422
+ def create_keybindings(on_toggle_multiline=None, app=None, agent_provider=None, agent_name=None):
402
423
  """Create custom key bindings."""
403
424
  kb = KeyBindings()
404
425
 
@@ -463,6 +484,41 @@ def create_keybindings(on_toggle_multiline=None, app=None):
463
484
  if event.app:
464
485
  event.app.invalidate()
465
486
 
487
+ # Store reference to agent provider and agent name for clipboard functionality
488
+ kb.agent_provider = agent_provider
489
+ kb.current_agent_name = agent_name
490
+
491
+ @kb.add("c-y")
492
+ async def _(event) -> None:
493
+ """Ctrl+Y: Copy last assistant response to clipboard."""
494
+ if kb.agent_provider and kb.current_agent_name:
495
+ try:
496
+ # Get the agent
497
+ if hasattr(kb.agent_provider, "_agent"):
498
+ agent = kb.agent_provider._agent(kb.current_agent_name)
499
+ else:
500
+ agent = kb.agent_provider
501
+
502
+ # Get message history
503
+ if hasattr(agent, "_llm") and agent._llm and agent._llm.message_history:
504
+ # Find last assistant message
505
+ for msg in reversed(agent._llm.message_history):
506
+ if msg.role == "assistant":
507
+ content = msg.last_text()
508
+ import pyperclip
509
+
510
+ pyperclip.copy(content)
511
+ rich_print("\n[green]✓ Copied to clipboard[/green]")
512
+ return
513
+
514
+ rich_print("\n[yellow]No assistant messages found[/yellow]")
515
+ else:
516
+ rich_print("\n[yellow]No message history available[/yellow]")
517
+ except Exception as e:
518
+ rich_print(f"\n[red]Error copying: {e}[/red]")
519
+ else:
520
+ rich_print("[yellow]Clipboard copy not available in this context[/yellow]")
521
+
466
522
  return kb
467
523
 
468
524
 
@@ -527,6 +583,7 @@ async def get_enhanced_input(
527
583
  shortcuts = [
528
584
  ("Ctrl+T", toggle_text),
529
585
  ("Ctrl+E", "External"),
586
+ ("Ctrl+Y", "Copy"),
530
587
  ("Ctrl+L", "Clear"),
531
588
  ("↑/↓", "History"),
532
589
  ]
@@ -569,7 +626,12 @@ async def get_enhanced_input(
569
626
  )
570
627
 
571
628
  # Create key bindings with a reference to the app
572
- bindings = create_keybindings(on_toggle_multiline=on_multiline_toggle, app=session.app)
629
+ bindings = create_keybindings(
630
+ on_toggle_multiline=on_multiline_toggle,
631
+ app=session.app,
632
+ agent_provider=agent_provider,
633
+ agent_name=agent_name,
634
+ )
573
635
  session.app.key_bindings = bindings
574
636
 
575
637
  # Create formatted prompt text
@@ -619,6 +681,8 @@ async def get_enhanced_input(
619
681
  return "LIST_AGENTS"
620
682
  elif cmd == "usage":
621
683
  return "SHOW_USAGE"
684
+ elif cmd == "markdown":
685
+ return "MARKDOWN"
622
686
  elif cmd == "prompt":
623
687
  # Handle /prompt with no arguments as interactive mode
624
688
  if len(cmd_parts) > 1:
@@ -792,16 +856,18 @@ async def handle_special_commands(command, agent_app=None):
792
856
  rich_print(" /help - Show this help")
793
857
  rich_print(" /clear - Clear screen")
794
858
  rich_print(" /agents - List available agents")
795
- rich_print(" /prompts - List and select MCP prompts")
796
859
  rich_print(" /prompt <name> - Apply a specific prompt by name")
797
860
  rich_print(" /usage - Show current usage statistics")
861
+ rich_print(" /markdown - Show last assistant message without markdown formatting")
798
862
  rich_print(" @agent_name - Switch to agent")
799
863
  rich_print(" STOP - Return control back to the workflow")
800
864
  rich_print(" EXIT - Exit fast-agent, terminating any running workflows")
801
865
  rich_print("\n[bold]Keyboard Shortcuts:[/bold]")
802
866
  rich_print(" Enter - Submit (normal mode) / New line (multiline mode)")
803
- rich_print(" Ctrl+Enter - Always submit (in any mode)")
867
+ rich_print(" Ctrl+Enter - Always submit (in any mode)")
804
868
  rich_print(" Ctrl+T - Toggle multiline mode")
869
+ rich_print(" Ctrl+E - Edit in external editor")
870
+ rich_print(" Ctrl+Y - Copy last assistant response to clipboard")
805
871
  rich_print(" Ctrl+L - Clear input")
806
872
  rich_print(" Up/Down - Navigate history")
807
873
  return True
@@ -827,6 +893,10 @@ async def handle_special_commands(command, agent_app=None):
827
893
  # Return a dictionary to signal that usage should be shown
828
894
  return {"show_usage": True}
829
895
 
896
+ elif command == "MARKDOWN":
897
+ # Return a dictionary to signal that markdown display should be shown
898
+ return {"show_markdown": True}
899
+
830
900
  elif command == "SELECT_PROMPT" or (
831
901
  isinstance(command, str) and command.startswith("SELECT_PROMPT:")
832
902
  ):
@@ -314,7 +314,7 @@ class FastAgent:
314
314
  self.agents,
315
315
  model_factory_func,
316
316
  )
317
-
317
+
318
318
  # Validate API keys after agent creation
319
319
  validate_provider_keys_post_creation(active_agents)
320
320
 
@@ -435,6 +435,14 @@ class FastAgent:
435
435
  raise SystemExit(1)
436
436
 
437
437
  finally:
438
+ # Ensure progress display is stopped before showing usage summary
439
+ try:
440
+ from mcp_agent.progress_display import progress_display
441
+
442
+ progress_display.stop()
443
+ except: # noqa: E722
444
+ pass
445
+
438
446
  # Print usage report before cleanup (show for user exits too)
439
447
  if active_agents and not had_error:
440
448
  self._print_usage_report(active_agents)