fast-agent-mcp 0.2.53__py3-none-any.whl → 0.2.55__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.53
3
+ Version: 0.2.55
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>=1.27.0
221
- Requires-Dist: mcp==1.12.1
221
+ Requires-Dist: mcp==1.12.4
222
222
  Requires-Dist: openai>=1.97.1
223
223
  Requires-Dist: opentelemetry-distro>=0.55b0
224
224
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.7.0
@@ -10,7 +10,7 @@ mcp_agent/progress_display.py,sha256=GeJU9VUt6qKsFVymG688hCMVCsAygG9ifiiEb5IcbN4
10
10
  mcp_agent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  mcp_agent/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  mcp_agent/agents/agent.py,sha256=EAYlcP1qqI1D0_CS808I806z1048FBjZQxxpcCZPeIU,3154
13
- mcp_agent/agents/base_agent.py,sha256=VCBWJ-l1zMQiBuONGzqcbqPUQfXK4oq-pBB5lJrMgQ0,32318
13
+ mcp_agent/agents/base_agent.py,sha256=4hyEdJJENxIDLCtYOAmRlmM7dRVE0JPEhOYktPTw1I0,34566
14
14
  mcp_agent/agents/workflow/__init__.py,sha256=HloteEW6kalvgR0XewpiFAqaQlMPlPJYg5p3K33IUzI,25
15
15
  mcp_agent/agents/workflow/chain_agent.py,sha256=eIlImirrSXkqBJmPuAJgOKis81Cl6lZEGM0-6IyaUV8,6105
16
16
  mcp_agent/agents/workflow/evaluator_optimizer.py,sha256=LT81m2B7fxgBZY0CorXFOZJbVhM5fnjDjfrcywO5UrM,12210
@@ -67,7 +67,7 @@ mcp_agent/llm/augmented_llm_playback.py,sha256=rLzgai496e2RlxqQp_Bp0U-Y1FF1SGsWl
67
67
  mcp_agent/llm/augmented_llm_silent.py,sha256=IUnK_1Byy4D9TG0Pj46LFeNezgSTQ8d6MQIHWAImBwE,1846
68
68
  mcp_agent/llm/augmented_llm_slow.py,sha256=DDSD8bL2flmQrVHZm-UDs7sR8aHRWkDOcOW-mX_GPok,2067
69
69
  mcp_agent/llm/memory.py,sha256=pTOaTDV3EA3X68yKwEtUAu7s0xGIQQ_cKBhfYUnfR0w,8614
70
- mcp_agent/llm/model_database.py,sha256=mxKcs7i3R1o09IrD2eao3voXE8tqcjkQaxOiwjnb0d4,11176
70
+ mcp_agent/llm/model_database.py,sha256=MXCf1dHwZZq_JeLUcuGshlfNyqTYPfS6MNr9zAM4fWs,11221
71
71
  mcp_agent/llm/model_factory.py,sha256=Dd3Drg9OyodkT4G4blFSbNiD8PAcphnZIWEmCjXP-QE,12203
72
72
  mcp_agent/llm/prompt_utils.py,sha256=yWQHykoK13QRF7evHUKxVF0SpVLN-Bsft0Yixzvn0g0,4825
73
73
  mcp_agent/llm/provider_key_manager.py,sha256=LSWIgcXlrUS4sfBvQBCya82qC6NcXQPYLtDHwHNOXR4,3394
@@ -77,7 +77,7 @@ mcp_agent/llm/sampling_format_converter.py,sha256=xGz4odHpOcP7--eFaJaFtUR8eR9jxZ
77
77
  mcp_agent/llm/usage_tracking.py,sha256=rF6v8QQDam8QbvlP4jzHljKqvuNHExeYDLkUMI86czY,16073
78
78
  mcp_agent/llm/providers/__init__.py,sha256=heVxtmuqFJOnjjxHz4bWSqTAxXoN1E8twC_gQ_yJpHk,265
79
79
  mcp_agent/llm/providers/anthropic_utils.py,sha256=vYDN5G5jKMhD2CQg8veJYab7tvvzYkDMq8M1g_hUAQg,3275
80
- mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=JlRfhohIQQlo5RgM1B2t4ITLC9dok8LQNKLf0BK8Ai8,1158
80
+ mcp_agent/llm/providers/augmented_llm_aliyun.py,sha256=Th4qeyihOSfTrojPw8YsgzEyaDwhybk7hkXkFjH-1dY,1277
81
81
  mcp_agent/llm/providers/augmented_llm_anthropic.py,sha256=U8znA9HSCOx4FlhIjl-J29nbYc8Y-T6BXevtXuDafio,30352
82
82
  mcp_agent/llm/providers/augmented_llm_azure.py,sha256=Xoo6dFst6L9SaGKurqptwwTUzr-sYsolZ-AFb_79puc,6098
83
83
  mcp_agent/llm/providers/augmented_llm_bedrock.py,sha256=nfby1udL07zPTOLlN_tFxd1h0JRioo2oIW7v4iP4Bnk,82267
@@ -85,8 +85,8 @@ mcp_agent/llm/providers/augmented_llm_deepseek.py,sha256=vphkYMFyukaejBw8SkCN-Mq
85
85
  mcp_agent/llm/providers/augmented_llm_generic.py,sha256=5Uq8ZBhcFuQTt7koP_5ykolREh2iWu8zKhNbh3pM9lQ,1210
86
86
  mcp_agent/llm/providers/augmented_llm_google_native.py,sha256=c6zczfs-Iw70j3OYELHJ4S7CRwAddkeXinex_yLMhmU,22194
87
87
  mcp_agent/llm/providers/augmented_llm_google_oai.py,sha256=g_g46h-YuxqbRZiO_dVo5zO2OkX1yx7nb6xDaQbOvWs,1137
88
- mcp_agent/llm/providers/augmented_llm_groq.py,sha256=5pqWgOoEJpvL230rJekBNlmBzUegbgwYitArlXgAmY0,4424
89
- mcp_agent/llm/providers/augmented_llm_openai.py,sha256=Rd5M1yYJ7r-Ln4RlL_j2ZbJ8HqQJpagO2T2Zh1vBwCY,25392
88
+ mcp_agent/llm/providers/augmented_llm_groq.py,sha256=Nj4X7wL7nOz_JYC-3bFOWut-hleZxGqWHNe0U-0ga8Y,4419
89
+ mcp_agent/llm/providers/augmented_llm_openai.py,sha256=d5WeCU6smP7a5egZOBpblF62mK5kOzK4tn2YeQoK34A,25401
90
90
  mcp_agent/llm/providers/augmented_llm_openrouter.py,sha256=m3wS83fabBOmaZJH9gQ9sFw_2TB4xTb44WCOPB-2NJ4,2001
91
91
  mcp_agent/llm/providers/augmented_llm_tensorzero_openai.py,sha256=D53Fry2AfBLOB5z9hM19U6_HMJeVNTpiBCAJb11ulNg,5503
92
92
  mcp_agent/llm/providers/augmented_llm_xai.py,sha256=MhlX91IUNynQ_NDknx4EQJLwg-NbR8lcHS1P4JuLOnA,1433
@@ -110,10 +110,10 @@ mcp_agent/mcp/elicitation_factory.py,sha256=gY0gEsF8Jdg01nSsrVbbl62ZS1A725QgDRB6
110
110
  mcp_agent/mcp/elicitation_handlers.py,sha256=w2S4kBn05pIKdq2-X13MErinFg5jSElwFsoTuW3zFSs,6618
111
111
  mcp_agent/mcp/gen_client.py,sha256=fAVwFVCgSamw4PwoWOV4wrK9TABx1S_zZv8BctRyF2k,3030
112
112
  mcp_agent/mcp/hf_auth.py,sha256=7szw4rkwRyK3J-sUTcVZHdwoLIZqlYo8XolJnZdjOww,4571
113
- mcp_agent/mcp/interfaces.py,sha256=pe8WKvu3dnNnPWmrkDlu15xdkhuRDAjLUMn2vIE0Mj8,7963
113
+ mcp_agent/mcp/interfaces.py,sha256=5y7zuXkpGCfsJfZOAEZAZtbFd5rAKjn7oG4JoblPHZ4,8070
114
114
  mcp_agent/mcp/logger_textio.py,sha256=vljC1BtNTCxBAda9ExqNB-FwVNUZIuJT3h1nWmCjMws,3172
115
115
  mcp_agent/mcp/mcp_agent_client_session.py,sha256=ssRgxMOzyCPyAr25AeRBz3Xr-08OBdmsJf8A-ofc3bY,9115
116
- mcp_agent/mcp/mcp_aggregator.py,sha256=3L_UDxg7nz_Cp1hHVxxCrhDybxg-Bg2QH8e0F8x1_W4,51377
116
+ mcp_agent/mcp/mcp_aggregator.py,sha256=6fZTgoiUfE7YHjLug1ZQ2VtKYj8HVe_diMwNN6npPGk,53343
117
117
  mcp_agent/mcp/mcp_connection_manager.py,sha256=dJxjnv2IRzlFIxrbPFl39-pmGcZHgyeMXVlMfqpREhE,17974
118
118
  mcp_agent/mcp/mime_utils.py,sha256=difepNR_gpb4MpMLkBRAoyhDk-AjXUHTiqKvT_VwS1o,1805
119
119
  mcp_agent/mcp/prompt_message_multipart.py,sha256=-oSO0mnc5gkSgulE1gAntPEwAKF4asOjEeVyLjhYrEk,4336
@@ -185,8 +185,8 @@ mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKv
185
185
  mcp_agent/tools/tool_definition.py,sha256=L3Pxl-uLEXqlVoo-bYuFTFALeI-2pIU44YgFhsTKEtM,398
186
186
  mcp_agent/ui/console_display.py,sha256=XXrHr950wSBSedEKUaaGkXjOzuFpQYzUKKiyaZ58Mps,28280
187
187
  mcp_agent/ui/console_display_legacy.py,sha256=sm2v61-IPVafbF7uUaOyhO2tW_zgFWOjNS83IEWqGgI,14931
188
- fast_agent_mcp-0.2.53.dist-info/METADATA,sha256=WT16JT-7AyeRZtVwKEtC0-Gxqj_OzdpHpZ1foFs_x4M,31048
189
- fast_agent_mcp-0.2.53.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
190
- fast_agent_mcp-0.2.53.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
191
- fast_agent_mcp-0.2.53.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
192
- fast_agent_mcp-0.2.53.dist-info/RECORD,,
188
+ fast_agent_mcp-0.2.55.dist-info/METADATA,sha256=wJSX8ZuwOm6h7kbWev3_cv1CQRDHT0C60xwlE9tXPqE,31048
189
+ fast_agent_mcp-0.2.55.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
190
+ fast_agent_mcp-0.2.55.dist-info/entry_points.txt,sha256=QaX5kLdI0VdMPRdPUF1nkG_WdLUTNjp_icW6e3EhNYU,232
191
+ fast_agent_mcp-0.2.55.dist-info/licenses/LICENSE,sha256=Gx1L3axA4PnuK4FxsbX87jQ1opoOkSFfHHSytW6wLUU,10935
192
+ fast_agent_mcp-0.2.55.dist-info/RECORD,,
@@ -783,6 +783,60 @@ class BaseAgent(MCPAggregator, AgentProtocol):
783
783
 
784
784
  return result
785
785
 
786
+ async def list_mcp_tools(self, server_name: str | None = None) -> Mapping[str, List[Tool]]:
787
+ """
788
+ List all tools available to this agent, grouped by server and filtered by configuration.
789
+
790
+ Args:
791
+ server_name: Optional server name to list tools from
792
+
793
+ Returns:
794
+ Dictionary mapping server names to lists of Tool objects (with original names, not namespaced)
795
+ """
796
+ if not self.initialized:
797
+ await self.initialize()
798
+
799
+ # Get all tools from the parent class
800
+ result = await super().list_mcp_tools(server_name)
801
+
802
+ # Apply filtering if tools are specified in config
803
+ if self.config.tools is not None:
804
+ filtered_result = {}
805
+ for server, tools in result.items():
806
+ # Check if this server has tool filters
807
+ if server in self.config.tools:
808
+ filtered_tools = []
809
+ for tool in tools:
810
+ # Check if tool matches any pattern for this server
811
+ for pattern in self.config.tools[server]:
812
+ if self._matches_pattern(tool.name, pattern, server):
813
+ filtered_tools.append(tool)
814
+ break
815
+ if filtered_tools:
816
+ filtered_result[server] = filtered_tools
817
+ result = filtered_result
818
+
819
+ # Add human input tool to a special server if human input is configured
820
+ if self.human_input_callback:
821
+ from mcp.server.fastmcp.tools import Tool as FastTool
822
+
823
+ human_input_tool: FastTool = FastTool.from_function(self.request_human_input)
824
+ special_server_name = "__human_input__"
825
+
826
+ # If the special server doesn't exist in result, create it
827
+ if special_server_name not in result:
828
+ result[special_server_name] = []
829
+
830
+ result[special_server_name].append(
831
+ Tool(
832
+ name=HUMAN_INPUT_TOOL_NAME,
833
+ description=human_input_tool.description,
834
+ inputSchema=human_input_tool.parameters,
835
+ )
836
+ )
837
+
838
+ return result
839
+
786
840
  @property
787
841
  def agent_type(self) -> AgentType:
788
842
  """
@@ -91,7 +91,10 @@ class ModelDatabase:
91
91
  )
92
92
 
93
93
  QWEN_STANDARD = ModelParameters(
94
- context_window=32000, max_output_tokens=8192, tokenizes=QWEN_MULTIMODAL
94
+ context_window=32000,
95
+ max_output_tokens=8192,
96
+ tokenizes=QWEN_MULTIMODAL,
97
+ json_mode="object",
95
98
  )
96
99
  QWEN3_REASONER = ModelParameters(
97
100
  context_window=131072,
@@ -1,24 +1,26 @@
1
1
  from mcp_agent.core.request_params import RequestParams
2
2
  from mcp_agent.llm.provider_types import Provider
3
+ from mcp_agent.llm.providers.augmented_llm_groq import GroqAugmentedLLM
3
4
  from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
4
5
 
5
6
  ALIYUN_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
6
7
  DEFAULT_QWEN_MODEL = "qwen-turbo"
7
8
 
8
9
 
9
- class AliyunAugmentedLLM(OpenAIAugmentedLLM):
10
+ class AliyunAugmentedLLM(GroqAugmentedLLM):
10
11
  def __init__(self, *args, **kwargs) -> None:
11
- super().__init__(*args, provider=Provider.ALIYUN, **kwargs)
12
+ OpenAIAugmentedLLM.__init__(self, *args, provider=Provider.ALIYUN, **kwargs)
12
13
 
13
14
  def _initialize_default_params(self, kwargs: dict) -> RequestParams:
14
15
  """Initialize Aliyun-specific default parameters"""
15
16
  # Get base defaults from parent (includes ModelDatabase lookup)
16
17
  base_params = super()._initialize_default_params(kwargs)
17
-
18
+
18
19
  # Override with Aliyun-specific settings
19
20
  chosen_model = kwargs.get("model", DEFAULT_QWEN_MODEL)
20
21
  base_params.model = chosen_model
21
-
22
+ base_params.parallel_tool_calls = True
23
+
22
24
  return base_params
23
25
 
24
26
  def _base_url(self) -> str:
@@ -27,3 +29,4 @@ class AliyunAugmentedLLM(OpenAIAugmentedLLM):
27
29
  base_url = self.context.config.aliyun.base_url
28
30
 
29
31
  return base_url if base_url else ALIYUN_BASE_URL
32
+
@@ -46,7 +46,7 @@ class GroqAugmentedLLM(OpenAIAugmentedLLM):
46
46
  assert self.default_request_params
47
47
  llm_model = self.default_request_params.model or DEFAULT_GROQ_MODEL
48
48
  json_mode: str | None = ModelDatabase.get_json_mode(llm_model)
49
- if "json_object" == json_mode:
49
+ if "object" == json_mode:
50
50
  request_params.response_format = {"type": "json_object"}
51
51
 
52
52
  # Get the full schema and extract just the properties
@@ -321,20 +321,20 @@ class OpenAIAugmentedLLM(AugmentedLLM[ChatCompletionMessageParam, ChatCompletion
321
321
 
322
322
  response = await self.aggregator.list_tools()
323
323
  available_tools: List[ChatCompletionToolParam] | None = [
324
- ChatCompletionToolParam(
325
- type="function",
326
- function={
324
+ {
325
+ "type": "function",
326
+ "function": {
327
327
  "name": tool.name,
328
328
  "description": tool.description if tool.description else "",
329
329
  "parameters": self.adjust_schema(tool.inputSchema),
330
330
  },
331
- )
331
+ }
332
332
  for tool in response.tools
333
333
  ]
334
334
 
335
335
  if not available_tools:
336
- if self.provider == Provider.DEEPSEEK:
337
- available_tools = None # deepseek does not allow empty array
336
+ if self.provider in [Provider.DEEPSEEK, Provider.ALIYUN]:
337
+ available_tools = None # deepseek/aliyun does not allow empty array
338
338
  else:
339
339
  available_tools = []
340
340
 
@@ -25,7 +25,7 @@ from a2a.types import AgentCard
25
25
  from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
26
26
  from deprecated import deprecated
27
27
  from mcp import ClientSession
28
- from mcp.types import GetPromptResult, Prompt, PromptMessage, ReadResourceResult
28
+ from mcp.types import GetPromptResult, Prompt, PromptMessage, ReadResourceResult, Tool
29
29
  from pydantic import BaseModel
30
30
 
31
31
  from mcp_agent.core.agent_types import AgentType
@@ -203,6 +203,8 @@ class AgentProtocol(AugmentedLLMProtocol, Protocol):
203
203
 
204
204
  async def list_resources(self, server_name: str | None = None) -> Mapping[str, List[str]]: ...
205
205
 
206
+ async def list_mcp_tools(self, server_name: str | None = None) -> Mapping[str, List[Tool]]: ...
207
+
206
208
  async def get_resource(
207
209
  self, resource_uri: str, server_name: str | None = None
208
210
  ) -> ReadResourceResult:
@@ -1232,3 +1232,55 @@ class MCPAggregator(ContextDependent):
1232
1232
  logger.error(f"Error fetching resources from {s_name}: {e}")
1233
1233
 
1234
1234
  return results
1235
+
1236
+ async def list_mcp_tools(self, server_name: str | None = None) -> Dict[str, List[Tool]]:
1237
+ """
1238
+ List available tools from one or all servers, grouped by server name.
1239
+
1240
+ Args:
1241
+ server_name: Optional server name to list tools from. If not provided,
1242
+ lists tools from all servers.
1243
+
1244
+ Returns:
1245
+ Dictionary mapping server names to lists of Tool objects (with original names, not namespaced)
1246
+ """
1247
+ if not self.initialized:
1248
+ await self.load_servers()
1249
+
1250
+ results: Dict[str, List[Tool]] = {}
1251
+
1252
+ # Get the list of servers to check
1253
+ servers_to_check = [server_name] if server_name else self.server_names
1254
+
1255
+ # For each server, try to list its tools
1256
+ for s_name in servers_to_check:
1257
+ if s_name not in self.server_names:
1258
+ logger.error(f"Server '{s_name}' not found")
1259
+ continue
1260
+
1261
+ # Initialize empty list for this server
1262
+ results[s_name] = []
1263
+
1264
+ # Check if server supports tools capability
1265
+ if not await self.server_supports_feature(s_name, "tools"):
1266
+ logger.debug(f"Server '{s_name}' does not support tools")
1267
+ continue
1268
+
1269
+ try:
1270
+ # Use the _execute_on_server method to call list_tools on the server
1271
+ result = await self._execute_on_server(
1272
+ server_name=s_name,
1273
+ operation_type="tools-list",
1274
+ operation_name="",
1275
+ method_name="list_tools",
1276
+ method_args={},
1277
+ )
1278
+
1279
+ # Get tools from result (these have original names, not namespaced)
1280
+ tools = getattr(result, "tools", [])
1281
+ results[s_name] = tools
1282
+
1283
+ except Exception as e:
1284
+ logger.error(f"Error fetching tools from {s_name}: {e}")
1285
+
1286
+ return results