mcp-use 1.3.8__py3-none-any.whl → 1.3.9__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 mcp-use might be problematic. Click here for more details.

mcp_use/__init__.py CHANGED
@@ -25,7 +25,6 @@ __all__ = [
25
25
  "StdioConnector",
26
26
  "WebSocketConnector",
27
27
  "HttpConnector",
28
- "create_session_from_config",
29
28
  "load_config_file",
30
29
  "logger",
31
30
  "MCP_USE_DEBUG",
mcp_use/adapters/base.py CHANGED
@@ -91,14 +91,14 @@ class BaseAdapter(ABC):
91
91
 
92
92
  connector_tools = []
93
93
  # Now create tools for each MCP tool
94
- for tool in connector.tools:
94
+ for tool in await connector.list_tools():
95
95
  # Convert the tool and add it to the list if conversion was successful
96
96
  converted_tool = self._convert_tool(tool, connector)
97
97
  if converted_tool:
98
98
  connector_tools.append(converted_tool)
99
99
 
100
100
  # Convert resources to tools so that agents can access resource content directly
101
- resources_list = connector.resources or []
101
+ resources_list = await connector.list_resources() or []
102
102
  if resources_list:
103
103
  for resource in resources_list:
104
104
  converted_resource = self._convert_resource(resource, connector)
@@ -106,7 +106,7 @@ class BaseAdapter(ABC):
106
106
  connector_tools.append(converted_resource)
107
107
 
108
108
  # Convert prompts to tools so that agents can retrieve prompt content
109
- prompts_list = connector.prompts or []
109
+ prompts_list = await connector.list_prompts() or []
110
110
  if prompts_list:
111
111
  for prompt in prompts_list:
112
112
  converted_prompt = self._convert_prompt(prompt, connector)
@@ -21,6 +21,7 @@ from mcp.types import (
21
21
  from pydantic import BaseModel, Field, create_model
22
22
 
23
23
  from ..connectors.base import BaseConnector
24
+ from ..errors.error_formatting import format_error
24
25
  from ..logging import logger
25
26
  from .base import BaseAdapter
26
27
 
@@ -159,11 +160,11 @@ class LangChainAdapter(BaseAdapter):
159
160
  except Exception as e:
160
161
  # Log the exception for debugging
161
162
  logger.error(f"Error parsing tool result: {e}")
162
- return f"Error parsing result: {e!s}; Raw content: {tool_result.content!r}"
163
+ return format_error(e, tool=self.name, tool_content=tool_result.content)
163
164
 
164
165
  except Exception as e:
165
166
  if self.handle_tool_error:
166
- return f"Error executing MCP tool: {str(e)}"
167
+ return format_error(e, tool=self.name) # Format the error to make LLM understand it
167
168
  raise
168
169
 
169
170
  return McpToLangChainAdapter()
@@ -204,7 +205,7 @@ class LangChainAdapter(BaseAdapter):
204
205
  return content_decoded
205
206
  except Exception as e:
206
207
  if self.handle_tool_error:
207
- return f"Error reading resource: {str(e)}"
208
+ return format_error(e, tool=self.name) # Format the error to make LLM understand it
208
209
  raise
209
210
 
210
211
  return ResourceTool()
@@ -261,7 +262,7 @@ class LangChainAdapter(BaseAdapter):
261
262
  return result.messages
262
263
  except Exception as e:
263
264
  if self.handle_tool_error:
264
- return f"Error fetching prompt: {str(e)}"
265
+ return format_error(e, tool=self.name) # Format the error to make LLM understand it
265
266
  raise
266
267
 
267
268
  return PromptTool()
mcp_use/agents/remote.py CHANGED
@@ -14,6 +14,11 @@ from ..logging import logger
14
14
 
15
15
  T = TypeVar("T", bound=BaseModel)
16
16
 
17
+ # API endpoint constants
18
+ API_CHATS_ENDPOINT = "/api/v1/chats"
19
+ API_CHAT_EXECUTE_ENDPOINT = "/api/v1/chats/{chat_id}/execute"
20
+ API_CHAT_DELETE_ENDPOINT = "/api/v1/chats/{chat_id}"
21
+
17
22
 
18
23
  class RemoteAgent:
19
24
  """Agent that executes remotely via API."""
@@ -28,6 +33,7 @@ class RemoteAgent:
28
33
  """
29
34
  self.agent_id = agent_id
30
35
  self.base_url = base_url
36
+ self._chat_id = None # Persistent chat session
31
37
 
32
38
  # Handle API key validation
33
39
  if api_key is None:
@@ -103,6 +109,49 @@ class RemoteAgent:
103
109
  return output_schema.model_validate({"content": str(result_data)})
104
110
  raise
105
111
 
112
+ async def _create_chat_session(self, query: str) -> str:
113
+ """Create a persistent chat session for the agent.
114
+ Args:
115
+ query: The initial query (not used in title anymore)
116
+ Returns:
117
+ The chat ID of the created session
118
+ Raises:
119
+ RuntimeError: If chat creation fails
120
+ """
121
+ chat_payload = {
122
+ "title": f"Remote Agent Session - {self.agent_id}",
123
+ "agent_id": self.agent_id,
124
+ "type": "agent_execution",
125
+ }
126
+
127
+ headers = {"Content-Type": "application/json", "x-api-key": self.api_key}
128
+ chat_url = f"{self.base_url}{API_CHATS_ENDPOINT}"
129
+
130
+ logger.info(f"📝 Creating chat session for agent {self.agent_id}")
131
+
132
+ try:
133
+ chat_response = await self._client.post(chat_url, json=chat_payload, headers=headers)
134
+ chat_response.raise_for_status()
135
+
136
+ chat_data = chat_response.json()
137
+ chat_id = chat_data["id"]
138
+ logger.info(f"✅ Chat session created: {chat_id}")
139
+ return chat_id
140
+
141
+ except httpx.HTTPStatusError as e:
142
+ status_code = e.response.status_code
143
+ response_text = e.response.text
144
+
145
+ if status_code == 404:
146
+ raise RuntimeError(
147
+ f"Agent not found: Agent '{self.agent_id}' does not exist or you don't have access to it. "
148
+ "Please verify the agent ID and ensure it exists in your account."
149
+ ) from e
150
+ else:
151
+ raise RuntimeError(f"Failed to create chat session: {status_code} - {response_text}") from e
152
+ except Exception as e:
153
+ raise RuntimeError(f"Failed to create chat session: {str(e)}") from e
154
+
106
155
  async def run(
107
156
  self,
108
157
  query: str,
@@ -126,20 +175,28 @@ class RemoteAgent:
126
175
  if external_history is not None:
127
176
  logger.warning("External history is not yet supported for remote execution")
128
177
 
129
- payload = {"query": query, "max_steps": max_steps or 10}
178
+ try:
179
+ logger.info(f"🌐 Executing query on remote agent {self.agent_id}")
130
180
 
131
- # Add structured output schema if provided
132
- if output_schema is not None:
133
- payload["output_schema"] = self._pydantic_to_json_schema(output_schema)
134
- logger.info(f"🔧 Using structured output with schema: {output_schema.__name__}")
181
+ # Step 1: Create a chat session for this agent (only if we don't have one)
182
+ if self._chat_id is None:
183
+ self._chat_id = await self._create_chat_session(query)
135
184
 
136
- headers = {"Content-Type": "application/json", "x-api-key": self.api_key}
185
+ chat_id = self._chat_id
137
186
 
138
- url = f"{self.base_url}/api/v1/agents/{self.agent_id}/run"
187
+ # Step 2: Execute the agent within the chat context
188
+ execution_payload = {"query": query, "max_steps": max_steps or 10}
139
189
 
140
- try:
141
- logger.info(f"🌐 Executing query on remote agent {self.agent_id}")
142
- response = await self._client.post(url, json=payload, headers=headers)
190
+ # Add structured output schema if provided
191
+ if output_schema is not None:
192
+ execution_payload["output_schema"] = self._pydantic_to_json_schema(output_schema)
193
+ logger.info(f"🔧 Using structured output with schema: {output_schema.__name__}")
194
+
195
+ headers = {"Content-Type": "application/json", "x-api-key": self.api_key}
196
+ execution_url = f"{self.base_url}{API_CHAT_EXECUTE_ENDPOINT.format(chat_id=chat_id)}"
197
+ logger.info(f"🚀 Executing agent in chat {chat_id}")
198
+
199
+ response = await self._client.post(execution_url, json=execution_payload, headers=headers)
143
200
  response.raise_for_status()
144
201
 
145
202
  result = response.json()
mcp_use/client.py CHANGED
@@ -9,7 +9,7 @@ import json
9
9
  import warnings
10
10
  from typing import Any
11
11
 
12
- from mcp.client.session import ElicitationFnT, SamplingFnT
12
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
13
13
 
14
14
  from mcp_use.types.sandbox import SandboxOptions
15
15
 
@@ -33,6 +33,8 @@ class MCPClient:
33
33
  sandbox_options: SandboxOptions | None = None,
34
34
  sampling_callback: SamplingFnT | None = None,
35
35
  elicitation_callback: ElicitationFnT | None = None,
36
+ message_handler: MessageHandlerFnT | None = None,
37
+ logging_callback: LoggingFnT | None = None,
36
38
  ) -> None:
37
39
  """Initialize a new MCP client.
38
40
 
@@ -51,6 +53,8 @@ class MCPClient:
51
53
  self.active_sessions: list[str] = []
52
54
  self.sampling_callback = sampling_callback
53
55
  self.elicitation_callback = elicitation_callback
56
+ self.message_handler = message_handler
57
+ self.logging_callback = logging_callback
54
58
  # Load configuration if provided
55
59
  if config is not None:
56
60
  if isinstance(config, str):
@@ -66,6 +70,8 @@ class MCPClient:
66
70
  sandbox_options: SandboxOptions | None = None,
67
71
  sampling_callback: SamplingFnT | None = None,
68
72
  elicitation_callback: ElicitationFnT | None = None,
73
+ message_handler: MessageHandlerFnT | None = None,
74
+ logging_callback: LoggingFnT | None = None,
69
75
  ) -> "MCPClient":
70
76
  """Create a MCPClient from a dictionary.
71
77
 
@@ -82,6 +88,8 @@ class MCPClient:
82
88
  sandbox_options=sandbox_options,
83
89
  sampling_callback=sampling_callback,
84
90
  elicitation_callback=elicitation_callback,
91
+ message_handler=message_handler,
92
+ logging_callback=logging_callback,
85
93
  )
86
94
 
87
95
  @classmethod
@@ -92,6 +100,8 @@ class MCPClient:
92
100
  sandbox_options: SandboxOptions | None = None,
93
101
  sampling_callback: SamplingFnT | None = None,
94
102
  elicitation_callback: ElicitationFnT | None = None,
103
+ message_handler: MessageHandlerFnT | None = None,
104
+ logging_callback: LoggingFnT | None = None,
95
105
  ) -> "MCPClient":
96
106
  """Create a MCPClient from a configuration file.
97
107
 
@@ -108,6 +118,8 @@ class MCPClient:
108
118
  sandbox_options=sandbox_options,
109
119
  sampling_callback=sampling_callback,
110
120
  elicitation_callback=elicitation_callback,
121
+ message_handler=message_handler,
122
+ logging_callback=logging_callback,
111
123
  )
112
124
 
113
125
  def add_server(
@@ -187,6 +199,8 @@ class MCPClient:
187
199
  sandbox_options=self.sandbox_options,
188
200
  sampling_callback=self.sampling_callback,
189
201
  elicitation_callback=self.elicitation_callback,
202
+ message_handler=self.message_handler,
203
+ logging_callback=self.logging_callback,
190
204
  )
191
205
 
192
206
  # Create the session
mcp_use/config.py CHANGED
@@ -7,17 +7,11 @@ This module provides functionality to load MCP configuration from JSON files.
7
7
  import json
8
8
  from typing import Any
9
9
 
10
- from mcp.client.session import ElicitationFnT, SamplingFnT
10
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
11
11
 
12
12
  from mcp_use.types.sandbox import SandboxOptions
13
13
 
14
- from .connectors import (
15
- BaseConnector,
16
- HttpConnector,
17
- SandboxConnector,
18
- StdioConnector,
19
- WebSocketConnector,
20
- )
14
+ from .connectors import BaseConnector, HttpConnector, SandboxConnector, StdioConnector, WebSocketConnector
21
15
  from .connectors.utils import is_stdio_server
22
16
 
23
17
 
@@ -40,6 +34,8 @@ def create_connector_from_config(
40
34
  sandbox_options: SandboxOptions | None = None,
41
35
  sampling_callback: SamplingFnT | None = None,
42
36
  elicitation_callback: ElicitationFnT | None = None,
37
+ message_handler: MessageHandlerFnT | None = None,
38
+ logging_callback: LoggingFnT | None = None,
43
39
  ) -> BaseConnector:
44
40
  """Create a connector based on server configuration.
45
41
  This function can be called with just the server_config parameter:
@@ -61,6 +57,8 @@ def create_connector_from_config(
61
57
  env=server_config.get("env", None),
62
58
  sampling_callback=sampling_callback,
63
59
  elicitation_callback=elicitation_callback,
60
+ message_handler=message_handler,
61
+ logging_callback=logging_callback,
64
62
  )
65
63
 
66
64
  # Sandboxed connector
@@ -72,6 +70,8 @@ def create_connector_from_config(
72
70
  e2b_options=sandbox_options,
73
71
  sampling_callback=sampling_callback,
74
72
  elicitation_callback=elicitation_callback,
73
+ message_handler=message_handler,
74
+ logging_callback=logging_callback,
75
75
  )
76
76
 
77
77
  # HTTP connector
@@ -84,6 +84,8 @@ def create_connector_from_config(
84
84
  sse_read_timeout=server_config.get("sse_read_timeout", 60 * 5),
85
85
  sampling_callback=sampling_callback,
86
86
  elicitation_callback=elicitation_callback,
87
+ message_handler=message_handler,
88
+ logging_callback=logging_callback,
87
89
  )
88
90
 
89
91
  # WebSocket connector
@@ -5,14 +5,27 @@ This module provides the base connector interface that all MCP connectors
5
5
  must implement.
6
6
  """
7
7
 
8
+ import warnings
8
9
  from abc import ABC, abstractmethod
9
10
  from datetime import timedelta
10
11
  from typing import Any
11
12
 
12
13
  from mcp import ClientSession, Implementation
13
- from mcp.client.session import ElicitationFnT, SamplingFnT
14
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
14
15
  from mcp.shared.exceptions import McpError
15
- from mcp.types import CallToolResult, GetPromptResult, Prompt, ReadResourceResult, Resource, Tool
16
+ from mcp.types import (
17
+ CallToolResult,
18
+ GetPromptResult,
19
+ Prompt,
20
+ PromptListChangedNotification,
21
+ ReadResourceResult,
22
+ Resource,
23
+ ResourceListChangedNotification,
24
+ ServerCapabilities,
25
+ ServerNotification,
26
+ Tool,
27
+ ToolListChangedNotification,
28
+ )
16
29
  from pydantic import AnyUrl
17
30
 
18
31
  import mcp_use
@@ -31,6 +44,8 @@ class BaseConnector(ABC):
31
44
  self,
32
45
  sampling_callback: SamplingFnT | None = None,
33
46
  elicitation_callback: ElicitationFnT | None = None,
47
+ message_handler: MessageHandlerFnT | None = None,
48
+ logging_callback: LoggingFnT | None = None,
34
49
  ):
35
50
  """Initialize base connector with common attributes."""
36
51
  self.client_session: ClientSession | None = None
@@ -43,6 +58,9 @@ class BaseConnector(ABC):
43
58
  self.auto_reconnect = True # Whether to automatically reconnect on connection loss (not configurable for now)
44
59
  self.sampling_callback = sampling_callback
45
60
  self.elicitation_callback = elicitation_callback
61
+ self.message_handler = message_handler
62
+ self.logging_callback = logging_callback
63
+ self.capabilities: ServerCapabilities | None = None
46
64
 
47
65
  @property
48
66
  def client_info(self) -> Implementation:
@@ -53,6 +71,20 @@ class BaseConnector(ABC):
53
71
  url="https://github.com/mcp-use/mcp-use",
54
72
  )
55
73
 
74
+ async def _internal_message_handler(self, message: Any) -> None:
75
+ """Wrap the user-provided message handler."""
76
+ if isinstance(message, ServerNotification):
77
+ if isinstance(message.root, ToolListChangedNotification):
78
+ logger.debug("Received tool list changed notification")
79
+ elif isinstance(message.root, ResourceListChangedNotification):
80
+ logger.debug("Received resource list changed notification")
81
+ elif isinstance(message.root, PromptListChangedNotification):
82
+ logger.debug("Received prompt list changed notification")
83
+
84
+ # Call the user's handler
85
+ if self.message_handler:
86
+ await self.message_handler(message)
87
+
56
88
  @abstractmethod
57
89
  async def connect(self) -> None:
58
90
  """Establish a connection to the MCP implementation."""
@@ -125,37 +157,37 @@ class BaseConnector(ABC):
125
157
  result = await self.client_session.initialize()
126
158
  self._initialized = True # Mark as initialized
127
159
 
128
- server_capabilities = result.capabilities
160
+ self.capabilities = result.capabilities
129
161
 
130
- if server_capabilities.tools:
162
+ if self.capabilities.tools:
131
163
  # Get available tools directly from client session
132
164
  try:
133
165
  tools_result = await self.client_session.list_tools()
134
166
  self._tools = tools_result.tools if tools_result else []
135
167
  except Exception as e:
136
- logger.error(f"Error listing tools: {e}")
168
+ logger.error(f"Error listing tools for connector {self.public_identifier}: {e}")
137
169
  self._tools = []
138
170
  else:
139
171
  self._tools = []
140
172
 
141
- if server_capabilities.resources:
173
+ if self.capabilities.resources:
142
174
  # Get available resources directly from client session
143
175
  try:
144
176
  resources_result = await self.client_session.list_resources()
145
177
  self._resources = resources_result.resources if resources_result else []
146
178
  except Exception as e:
147
- logger.error(f"Error listing resources: {e}")
179
+ logger.error(f"Error listing resources for connector {self.public_identifier}: {e}")
148
180
  self._resources = []
149
181
  else:
150
182
  self._resources = []
151
183
 
152
- if server_capabilities.prompts:
184
+ if self.capabilities.prompts:
153
185
  # Get available prompts directly from client session
154
186
  try:
155
187
  prompts_result = await self.client_session.list_prompts()
156
188
  self._prompts = prompts_result.prompts if prompts_result else []
157
189
  except Exception as e:
158
- logger.error(f"Error listing prompts: {e}")
190
+ logger.error(f"Error listing prompts for connector {self.public_identifier}: {e}")
159
191
  self._prompts = []
160
192
  else:
161
193
  self._prompts = []
@@ -170,21 +202,57 @@ class BaseConnector(ABC):
170
202
 
171
203
  @property
172
204
  def tools(self) -> list[Tool]:
173
- """Get the list of available tools."""
205
+ """Get the list of available tools.
206
+
207
+ .. deprecated::
208
+ This property is deprecated because it may return stale data when the server
209
+ sends list change notifications. Use `await list_tools()` instead to ensure
210
+ you always get the latest data.
211
+ """
212
+ warnings.warn(
213
+ "The 'tools' property is deprecated and may return stale data. "
214
+ "Use 'await list_tools()' instead to ensure fresh data.",
215
+ DeprecationWarning,
216
+ stacklevel=2,
217
+ )
174
218
  if self._tools is None:
175
219
  raise RuntimeError("MCP client is not initialized")
176
220
  return self._tools
177
221
 
178
222
  @property
179
223
  def resources(self) -> list[Resource]:
180
- """Get the list of available resources."""
224
+ """Get the list of available resources.
225
+
226
+ .. deprecated::
227
+ This property is deprecated because it may return stale data when the server
228
+ sends list change notifications. Use `await list_resources()` instead to ensure
229
+ you always get the latest data.
230
+ """
231
+ warnings.warn(
232
+ "The 'resources' property is deprecated and may return stale data. "
233
+ "Use 'await list_resources()' instead to ensure fresh data.",
234
+ DeprecationWarning,
235
+ stacklevel=2,
236
+ )
181
237
  if self._resources is None:
182
238
  raise RuntimeError("MCP client is not initialized")
183
239
  return self._resources
184
240
 
185
241
  @property
186
242
  def prompts(self) -> list[Prompt]:
187
- """Get the list of available prompts."""
243
+ """Get the list of available prompts.
244
+
245
+ .. deprecated::
246
+ This property is deprecated because it may return stale data when the server
247
+ sends list change notifications. Use `await list_prompts()' instead to ensure
248
+ you always get the latest data.
249
+ """
250
+ warnings.warn(
251
+ "The 'prompts' property is deprecated and may return stale data. "
252
+ "Use 'await list_prompts()' instead to ensure fresh data.",
253
+ DeprecationWarning,
254
+ stacklevel=2,
255
+ )
188
256
  if self._prompts is None:
189
257
  raise RuntimeError("MCP client is not initialized")
190
258
  return self._prompts
@@ -303,28 +371,39 @@ class BaseConnector(ABC):
303
371
  async def list_tools(self) -> list[Tool]:
304
372
  """List all available tools from the MCP implementation."""
305
373
 
374
+ if self.capabilities and not self.capabilities.tools:
375
+ logger.debug(f"Server {self.public_identifier} does not support tools")
376
+ return []
377
+
306
378
  # Ensure we're connected
307
379
  await self._ensure_connected()
308
380
 
309
381
  logger.debug("Listing tools")
310
382
  try:
311
383
  result = await self.client_session.list_tools()
384
+ self._tools = result.tools
312
385
  return result.tools
313
386
  except McpError as e:
314
- logger.error(f"Error listing tools: {e}")
387
+ logger.error(f"Error listing tools for connector {self.public_identifier}: {e}")
315
388
  return []
316
389
 
317
390
  async def list_resources(self) -> list[Resource]:
318
391
  """List all available resources from the MCP implementation."""
392
+
393
+ if self.capabilities and not self.capabilities.resources:
394
+ logger.debug(f"Server {self.public_identifier} does not support resources")
395
+ return []
396
+
319
397
  # Ensure we're connected
320
398
  await self._ensure_connected()
321
399
 
322
400
  logger.debug("Listing resources")
323
401
  try:
324
402
  result = await self.client_session.list_resources()
403
+ self._resources = result.resources
325
404
  return result.resources
326
405
  except McpError as e:
327
- logger.error(f"Error listing resources: {e}")
406
+ logger.warning(f"Error listing resources for connector {self.public_identifier}: {e}")
328
407
  return []
329
408
 
330
409
  async def read_resource(self, uri: AnyUrl) -> ReadResourceResult:
@@ -337,14 +416,20 @@ class BaseConnector(ABC):
337
416
 
338
417
  async def list_prompts(self) -> list[Prompt]:
339
418
  """List all available prompts from the MCP implementation."""
419
+
420
+ if self.capabilities and not self.capabilities.prompts:
421
+ logger.debug(f"Server {self.public_identifier} does not support prompts")
422
+ return []
423
+
340
424
  await self._ensure_connected()
341
425
 
342
426
  logger.debug("Listing prompts")
343
427
  try:
344
428
  result = await self.client_session.list_prompts()
429
+ self._prompts = result.prompts
345
430
  return result.prompts
346
431
  except McpError as e:
347
- logger.error(f"Error listing prompts: {e}")
432
+ logger.error(f"Error listing prompts for connector {self.public_identifier}: {e}")
348
433
  return []
349
434
 
350
435
  async def get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult:
@@ -7,7 +7,7 @@ through HTTP APIs with SSE or Streamable HTTP for transport.
7
7
 
8
8
  import httpx
9
9
  from mcp import ClientSession
10
- from mcp.client.session import ElicitationFnT, SamplingFnT
10
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
11
11
 
12
12
  from ..logging import logger
13
13
  from ..task_managers import SseConnectionManager, StreamableHttpConnectionManager
@@ -30,6 +30,8 @@ class HttpConnector(BaseConnector):
30
30
  sse_read_timeout: float = 60 * 5,
31
31
  sampling_callback: SamplingFnT | None = None,
32
32
  elicitation_callback: ElicitationFnT | None = None,
33
+ message_handler: MessageHandlerFnT | None = None,
34
+ logging_callback: LoggingFnT | None = None,
33
35
  ):
34
36
  """Initialize a new HTTP connector.
35
37
 
@@ -42,7 +44,12 @@ class HttpConnector(BaseConnector):
42
44
  sampling_callback: Optional sampling callback.
43
45
  elicitation_callback: Optional elicitation callback.
44
46
  """
45
- super().__init__(sampling_callback=sampling_callback, elicitation_callback=elicitation_callback)
47
+ super().__init__(
48
+ sampling_callback=sampling_callback,
49
+ elicitation_callback=elicitation_callback,
50
+ message_handler=message_handler,
51
+ logging_callback=logging_callback,
52
+ )
46
53
  self.base_url = base_url.rstrip("/")
47
54
  self.auth_token = auth_token
48
55
  self.headers = headers or {}
@@ -78,6 +85,8 @@ class HttpConnector(BaseConnector):
78
85
  write_stream,
79
86
  sampling_callback=self.sampling_callback,
80
87
  elicitation_callback=self.elicitation_callback,
88
+ message_handler=self._internal_message_handler,
89
+ logging_callback=self.logging_callback,
81
90
  client_info=self.client_info,
82
91
  )
83
92
  await test_client.__aenter__()
@@ -162,6 +171,8 @@ class HttpConnector(BaseConnector):
162
171
  write_stream,
163
172
  sampling_callback=self.sampling_callback,
164
173
  elicitation_callback=self.elicitation_callback,
174
+ message_handler=self._internal_message_handler,
175
+ logging_callback=self.logging_callback,
165
176
  client_info=self.client_info,
166
177
  )
167
178
  await self.client_session.__aenter__()
@@ -12,7 +12,7 @@ import time
12
12
 
13
13
  import aiohttp
14
14
  from mcp import ClientSession
15
- from mcp.client.session import ElicitationFnT, SamplingFnT
15
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
16
16
 
17
17
  from ..logging import logger
18
18
  from ..task_managers import SseConnectionManager
@@ -20,10 +20,7 @@ from ..task_managers import SseConnectionManager
20
20
  # Import E2B SDK components (optional dependency)
21
21
  try:
22
22
  logger.debug("Attempting to import e2b_code_interpreter...")
23
- from e2b_code_interpreter import (
24
- CommandHandle,
25
- Sandbox,
26
- )
23
+ from e2b_code_interpreter import CommandHandle, Sandbox
27
24
 
28
25
  logger.debug("Successfully imported e2b_code_interpreter")
29
26
  except ImportError as e:
@@ -53,6 +50,8 @@ class SandboxConnector(BaseConnector):
53
50
  sse_read_timeout: float = 60 * 5,
54
51
  sampling_callback: SamplingFnT | None = None,
55
52
  elicitation_callback: ElicitationFnT | None = None,
53
+ message_handler: MessageHandlerFnT | None = None,
54
+ logging_callback: LoggingFnT | None = None,
56
55
  ):
57
56
  """Initialize a new sandbox connector.
58
57
 
@@ -67,7 +66,12 @@ class SandboxConnector(BaseConnector):
67
66
  sampling_callback: Optional sampling callback.
68
67
  elicitation_callback: Optional elicitation callback.
69
68
  """
70
- super().__init__(sampling_callback=sampling_callback, elicitation_callback=elicitation_callback)
69
+ super().__init__(
70
+ sampling_callback=sampling_callback,
71
+ elicitation_callback=elicitation_callback,
72
+ message_handler=message_handler,
73
+ logging_callback=logging_callback,
74
+ )
71
75
  if Sandbox is None:
72
76
  raise ImportError(
73
77
  "E2B SDK (e2b-code-interpreter) not found. Please install it with "
@@ -227,6 +231,8 @@ class SandboxConnector(BaseConnector):
227
231
  write_stream,
228
232
  sampling_callback=self.sampling_callback,
229
233
  elicitation_callback=self.elicitation_callback,
234
+ message_handler=self._internal_message_handler,
235
+ logging_callback=self.logging_callback,
230
236
  client_info=self.client_info,
231
237
  )
232
238
  await self.client_session.__aenter__()
@@ -8,7 +8,7 @@ through the standard input/output streams.
8
8
  import sys
9
9
 
10
10
  from mcp import ClientSession, StdioServerParameters
11
- from mcp.client.session import ElicitationFnT, SamplingFnT
11
+ from mcp.client.session import ElicitationFnT, LoggingFnT, MessageHandlerFnT, SamplingFnT
12
12
 
13
13
  from ..logging import logger
14
14
  from ..task_managers import StdioConnectionManager
@@ -31,6 +31,8 @@ class StdioConnector(BaseConnector):
31
31
  errlog=sys.stderr,
32
32
  sampling_callback: SamplingFnT | None = None,
33
33
  elicitation_callback: ElicitationFnT | None = None,
34
+ message_handler: MessageHandlerFnT | None = None,
35
+ logging_callback: LoggingFnT | None = None,
34
36
  ):
35
37
  """Initialize a new stdio connector.
36
38
 
@@ -42,7 +44,12 @@ class StdioConnector(BaseConnector):
42
44
  sampling_callback: Optional callback to sample the client.
43
45
  elicitation_callback: Optional callback to elicit the client.
44
46
  """
45
- super().__init__(sampling_callback=sampling_callback, elicitation_callback=elicitation_callback)
47
+ super().__init__(
48
+ sampling_callback=sampling_callback,
49
+ elicitation_callback=elicitation_callback,
50
+ message_handler=message_handler,
51
+ logging_callback=logging_callback,
52
+ )
46
53
  self.command = command
47
54
  self.args = args or [] # Ensure args is never None
48
55
  self.env = env
@@ -69,6 +76,8 @@ class StdioConnector(BaseConnector):
69
76
  write_stream,
70
77
  sampling_callback=self.sampling_callback,
71
78
  elicitation_callback=self.elicitation_callback,
79
+ message_handler=self._internal_message_handler,
80
+ logging_callback=self.logging_callback,
72
81
  client_info=self.client_info,
73
82
  )
74
83
  await self.client_session.__aenter__()
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,29 @@
1
+ import traceback
2
+
3
+ from ..logging import logger
4
+
5
+ retryable_exceptions = (TimeoutError, ConnectionError) # We can add more exceptions here
6
+
7
+
8
+ def format_error(error: Exception, **context) -> dict:
9
+ """
10
+ Formats an exception into a structured format that can be understood by LLMs.
11
+
12
+ Args:
13
+ error: The exception to format.
14
+ **context: Additional context to include in the formatted error.
15
+
16
+ Returns:
17
+ A dictionary containing the formatted error.
18
+ """
19
+ formatted_context = {
20
+ "error": type(error).__name__,
21
+ "details": str(error),
22
+ "isRetryable": isinstance(error, retryable_exceptions),
23
+ "stack": traceback.format_exc(),
24
+ "code": getattr(error, "code", "UNKNOWN"),
25
+ }
26
+ formatted_context.update(context)
27
+
28
+ logger.error(f"Structured error: {formatted_context}") # For observability (maybe remove later)
29
+ return formatted_context
@@ -4,13 +4,7 @@ from mcp_use.client import MCPClient
4
4
  from mcp_use.logging import logger
5
5
 
6
6
  from ..adapters.base import BaseAdapter
7
- from .tools import (
8
- ConnectServerTool,
9
- DisconnectServerTool,
10
- GetActiveServerTool,
11
- ListServersTool,
12
- SearchToolsTool,
13
- )
7
+ from .tools import ConnectServerTool, DisconnectServerTool, GetActiveServerTool, ListServersTool, SearchToolsTool
14
8
 
15
9
 
16
10
  class ServerManager:
@@ -2,6 +2,7 @@ from typing import ClassVar
2
2
 
3
3
  from pydantic import BaseModel, Field
4
4
 
5
+ from mcp_use.errors.error_formatting import format_error
5
6
  from mcp_use.logging import logger
6
7
 
7
8
  from .base_tool import MCPServerTool
@@ -62,7 +63,7 @@ class ConnectServerTool(MCPServerTool):
62
63
 
63
64
  except Exception as e:
64
65
  logger.error(f"Error connecting to server '{server_name}': {e}")
65
- return f"Failed to connect to server '{server_name}': {str(e)}"
66
+ return format_error(e, server_name=server_name)
66
67
 
67
68
  def _run(self, server_name: str) -> str:
68
69
  """Synchronous version that raises a NotImplementedError - use _arun instead."""
@@ -2,6 +2,7 @@ from typing import ClassVar
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
5
+ from mcp_use.errors.error_formatting import format_error
5
6
  from mcp_use.logging import logger
6
7
 
7
8
  from .base_tool import MCPServerTool
@@ -36,7 +37,7 @@ class DisconnectServerTool(MCPServerTool):
36
37
  return f"Successfully disconnected from MCP server '{server_name}'."
37
38
  except Exception as e:
38
39
  logger.error(f"Error disconnecting from server '{server_name}': {e}")
39
- return f"Failed to disconnect from server '{server_name}': {str(e)}"
40
+ return format_error(e, server_name=server_name)
40
41
 
41
42
  async def _arun(self, **kwargs) -> str:
42
43
  """Async implementation of _run."""
@@ -2,6 +2,7 @@ from typing import ClassVar
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
5
+ from mcp_use.errors.error_formatting import format_error
5
6
  from mcp_use.logging import logger
6
7
 
7
8
  from .base_tool import MCPServerTool
@@ -44,6 +45,7 @@ class ListServersTool(MCPServerTool):
44
45
  result += f" {tool_count} tools available for this server\n"
45
46
  except Exception as e:
46
47
  logger.error(f"Unexpected error listing tools for server '{server_name}': {e}")
48
+ return format_error(e, server=server_name, operation="list_tools")
47
49
 
48
50
  return result
49
51
 
mcp_use/session.py CHANGED
@@ -5,8 +5,12 @@ This module provides a session manager for MCP connections,
5
5
  which handles authentication, initialization, and tool discovery.
6
6
  """
7
7
 
8
+ from datetime import timedelta
8
9
  from typing import Any
9
10
 
11
+ from mcp.types import CallToolResult, GetPromptResult, Prompt, ReadResourceResult, Resource, Tool
12
+ from pydantic import AnyUrl
13
+
10
14
  from .connectors.base import BaseConnector
11
15
 
12
16
 
@@ -82,3 +86,69 @@ class MCPSession:
82
86
  True if the connector is connected, False otherwise.
83
87
  """
84
88
  return self.connector.is_connected
89
+
90
+ # Convenience methods for MCP operations
91
+ async def call_tool(
92
+ self, name: str, arguments: dict[str, Any], read_timeout_seconds: timedelta | None = None
93
+ ) -> CallToolResult:
94
+ """Call an MCP tool.
95
+
96
+ Args:
97
+ name: The name of the tool to call.
98
+ arguments: The arguments to pass to the tool.
99
+ read_timeout_seconds: Optional timeout for the tool call.
100
+
101
+ Returns:
102
+ The result of the tool call.
103
+
104
+ Raises:
105
+ RuntimeError: If the connection is lost and cannot be reestablished.
106
+ """
107
+ return await self.connector.call_tool(name, arguments, read_timeout_seconds)
108
+
109
+ async def list_tools(self) -> list[Tool]:
110
+ """List all available tools from the MCP server.
111
+
112
+ Returns:
113
+ List of available tools.
114
+ """
115
+ return await self.connector.list_tools()
116
+
117
+ async def list_resources(self) -> list[Resource]:
118
+ """List all available resources from the MCP server.
119
+
120
+ Returns:
121
+ List of available resources.
122
+ """
123
+ return await self.connector.list_resources()
124
+
125
+ async def read_resource(self, uri: AnyUrl) -> ReadResourceResult:
126
+ """Read a resource by URI.
127
+
128
+ Args:
129
+ uri: The URI of the resource to read.
130
+
131
+ Returns:
132
+ The resource content.
133
+ """
134
+ return await self.connector.read_resource(uri)
135
+
136
+ async def list_prompts(self) -> list[Prompt]:
137
+ """List all available prompts from the MCP server.
138
+
139
+ Returns:
140
+ List of available prompts.
141
+ """
142
+ return await self.connector.list_prompts()
143
+
144
+ async def get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult:
145
+ """Get a prompt by name.
146
+
147
+ Args:
148
+ name: The name of the prompt to get.
149
+ arguments: Optional arguments for the prompt.
150
+
151
+ Returns:
152
+ The prompt result with messages.
153
+ """
154
+ return await self.connector.get_prompt(name, arguments)
@@ -11,10 +11,7 @@ from posthog import Posthog
11
11
  from scarf import ScarfEventLogger
12
12
 
13
13
  from mcp_use.logging import MCP_USE_DEBUG
14
- from mcp_use.telemetry.events import (
15
- BaseTelemetryEvent,
16
- MCPAgentExecutionEvent,
17
- )
14
+ from mcp_use.telemetry.events import BaseTelemetryEvent, MCPAgentExecutionEvent
18
15
  from mcp_use.telemetry.utils import get_package_version
19
16
  from mcp_use.utils import singleton
20
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-use
3
- Version: 1.3.8
3
+ Version: 1.3.9
4
4
  Summary: MCP Library for LLMs
5
5
  Author-email: Pietro Zullo <pietro.zullo@gmail.com>
6
6
  License: MIT
@@ -46,25 +46,30 @@ Description-Content-Type: text/markdown
46
46
  <div align="center">
47
47
  <div align="center" style="margin: 0 auto; max-width: 80%;">
48
48
  <picture>
49
- <source media="(prefers-color-scheme: dark)" srcset="static/logo_white.svg">
50
- <source media="(prefers-color-scheme: light)" srcset="static/logo_black.svg">
51
- <img alt="mcp use logo" src="./static/logo-white.svg" width="80%" style="margin: 20px auto;">
49
+ <source media="(prefers-color-scheme: dark)" srcset="static/logo-gh.jpg">
50
+ <source media="(prefers-color-scheme: light)" srcset="static/logo-gh.jpg">
51
+ <img alt="mcp use logo" src="./static/logo-gh.jpg" width="80%" style="margin: 20px auto;">
52
52
  </picture>
53
53
  </div>
54
54
 
55
55
  <br>
56
56
 
57
- # Connect any LLM to any MCP server
57
+ # Create MCP Clients and Agents
58
58
 
59
+ <p align="center">
60
+ <a href="https://www.producthunt.com/products/mcp-use?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-mcp&#0045;use" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1002629&theme=neutral&t=1754609432704" alt="mcp&#0045;use - Open&#0032;source&#0032;SDK&#0032;and&#0032;infra&#0032;for&#0032;MCP&#0032;servers&#0032;&#0038;&#0032;agents | Product Hunt" style="width: 150px; height: 32px;" width="150" height="32" /></a>
61
+ </p>
59
62
  <p align="center">
60
63
  <a href="https://github.com/pietrozullo/mcp-use/stargazers" alt="GitHub stars">
61
64
  <img src="https://img.shields.io/github/stars/pietrozullo/mcp-use?style=social" /></a>
65
+ <a href="https://pypi.org/project/mcp_use/" alt="PyPI Downloads">
66
+ <img src="https://static.pepy.tech/badge/mcp-use" /></a>
62
67
  <a href="https://pypi.org/project/mcp_use/" alt="PyPI Version">
63
68
  <img src="https://img.shields.io/pypi/v/mcp_use.svg"/></a>
69
+ <a href="https://github.com/mcp-use/mcp-use-ts" alt="TypeScript">
70
+ <img src="https://img.shields.io/badge/TypeScript-mcp--use-3178C6?logo=typescript&logoColor=white" /></a>
64
71
  <a href="https://github.com/pietrozullo/mcp-use/blob/main/LICENSE" alt="License">
65
72
  <img src="https://img.shields.io/github/license/pietrozullo/mcp-use" /></a>
66
- <a href="https://pypi.org/project/mcp_use/" alt="PyPI Downloads">
67
- <img src="https://static.pepy.tech/badge/mcp-use" /></a>
68
73
  <a href="https://docs.mcp-use.com" alt="Documentation">
69
74
  <img src="https://img.shields.io/badge/docs-mcp--use.com-blue" /></a>
70
75
  <a href="https://mcp-use.com" alt="Website">
@@ -88,10 +93,10 @@ Description-Content-Type: text/markdown
88
93
  - Visit the [mcp-use docs](https://docs.mcp-use.com/) to get started with mcp-use library
89
94
  - For the TypeScript version, visit [mcp-use-ts](https://github.com/mcp-use/mcp-use-ts)
90
95
 
91
- | Supports | |
92
- | :--- | :--- |
96
+ | Supports | |
97
+ | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
98
  | **Primitives** | [![Tools](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-tools&label=Tools&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Resources](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-resources&label=Resources&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Prompts](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-prompts&label=Prompts&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Sampling](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-sampling&label=Sampling&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Elicitation](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-elicitation&label=Elicitation&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
94
- | **Transports** | [![Stdio](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-stdio&label=Stdio&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![SSE](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-sse&label=SSE&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Streamable HTTP](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-streamableHttp&label=Streamable%20HTTP&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
99
+ | **Transports** | [![Stdio](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-stdio&label=Stdio&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![SSE](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-sse&label=SSE&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Streamable HTTP](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-streamableHttp&label=Streamable%20HTTP&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
95
100
 
96
101
  ## Features
97
102
 
@@ -417,29 +422,7 @@ if __name__ == "__main__":
417
422
  asyncio.run(run_blender_example())
418
423
  ```
419
424
 
420
- # Configuration File Support
421
-
422
- MCP-Use supports initialization from configuration files, making it easy to manage and switch between different MCP server setups:
423
-
424
- ```python
425
- import asyncio
426
- from mcp_use import create_session_from_config
427
-
428
- async def main():
429
- # Create an MCP session from a config file
430
- session = create_session_from_config("mcp-config.json")
431
-
432
- # Initialize the session
433
- await session.initialize()
434
-
435
- # Use the session...
436
-
437
- # Disconnect when done
438
- await session.disconnect()
439
-
440
- if __name__ == "__main__":
441
- asyncio.run(main())
442
- ```
425
+ # Configuration Support
443
426
 
444
427
  ## HTTP Connection Example
445
428
 
@@ -695,6 +678,47 @@ The `SandboxOptions` type provides configuration for the sandbox environment:
695
678
  - **Consistent environment**: Ensure consistent behavior across different systems
696
679
  - **Resource efficiency**: Offload resource-intensive tasks to cloud infrastructure
697
680
 
681
+ # Direct Tool Calls (Without LLM)
682
+
683
+ You can call MCP server tools directly without an LLM when you need programmatic control:
684
+
685
+ ```python
686
+ import asyncio
687
+ from mcp_use import MCPClient
688
+
689
+ async def call_tool_example():
690
+ config = {
691
+ "mcpServers": {
692
+ "everything": {
693
+ "command": "npx",
694
+ "args": ["-y", "@modelcontextprotocol/server-everything"],
695
+ }
696
+ }
697
+ }
698
+
699
+ client = MCPClient.from_dict(config)
700
+
701
+ try:
702
+ await client.create_all_sessions()
703
+ session = client.get_session("everything")
704
+
705
+ # Call tool directly
706
+ result = await session.call_tool(
707
+ name="add",
708
+ arguments={"a": 1, "b": 2}
709
+ )
710
+
711
+ print(f"Result: {result.content[0].text}") # Output: 3
712
+
713
+ finally:
714
+ await client.close_all_sessions()
715
+
716
+ if __name__ == "__main__":
717
+ asyncio.run(call_tool_example())
718
+ ```
719
+
720
+ See the complete example: [examples/direct_tool_call.py](examples/direct_tool_call.py)
721
+
698
722
  # Build a Custom Agent:
699
723
 
700
724
  You can also build your own custom agent using the LangChain adapter:
@@ -813,23 +837,27 @@ Thanks to all our amazing contributors!
813
837
  </tr>
814
838
  <tr>
815
839
  <td><img src="https://avatars.githubusercontent.com/u/38653995?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/patchy631/ai-engineering-hub"><strong>patchy631/ai-engineering-hub</strong></a></td>
816
- <td>⭐ 15189</td>
840
+ <td>⭐ 15920</td>
817
841
  </tr>
818
842
  <tr>
819
843
  <td><img src="https://avatars.githubusercontent.com/u/170207473?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/tavily-ai/meeting-prep-agent"><strong>tavily-ai/meeting-prep-agent</strong></a></td>
820
844
  <td>⭐ 129</td>
821
845
  </tr>
822
846
  <tr>
823
- <td><img src="https://avatars.githubusercontent.com/u/187057607?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/hud-evals/hud-sdk"><strong>hud-evals/hud-sdk</strong></a></td>
824
- <td>⭐ 75</td>
847
+ <td><img src="https://avatars.githubusercontent.com/u/164294848?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/buildfastwithai/gen-ai-experiments"><strong>buildfastwithai/gen-ai-experiments</strong></a></td>
848
+ <td>⭐ 93</td>
849
+ </tr>
850
+ <tr>
851
+ <td><img src="https://avatars.githubusercontent.com/u/187057607?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/hud-evals/hud-python"><strong>hud-evals/hud-python</strong></a></td>
852
+ <td>⭐ 76</td>
825
853
  </tr>
826
854
  <tr>
827
855
  <td><img src="https://avatars.githubusercontent.com/u/20041231?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/krishnaik06/MCP-CRASH-Course"><strong>krishnaik06/MCP-CRASH-Course</strong></a></td>
828
- <td>⭐ 58</td>
856
+ <td>⭐ 61</td>
829
857
  </tr>
830
858
  <tr>
831
859
  <td><img src="https://avatars.githubusercontent.com/u/54944174?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/larksuite/lark-samples"><strong>larksuite/lark-samples</strong></a></td>
832
- <td>⭐ 31</td>
860
+ <td>⭐ 35</td>
833
861
  </tr>
834
862
  <tr>
835
863
  <td><img src="https://avatars.githubusercontent.com/u/892404?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/truemagic-coder/solana-agent-app"><strong>truemagic-coder/solana-agent-app</strong></a></td>
@@ -845,11 +873,7 @@ Thanks to all our amazing contributors!
845
873
  </tr>
846
874
  <tr>
847
875
  <td><img src="https://avatars.githubusercontent.com/u/100749943?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/Deniscartin/mcp-cli"><strong>Deniscartin/mcp-cli</strong></a></td>
848
- <td>⭐ 18</td>
849
- </tr>
850
- <tr>
851
- <td><img src="https://avatars.githubusercontent.com/u/6688805?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/innovaccer/Healthcare-MCP"><strong>innovaccer/Healthcare-MCP</strong></a></td>
852
- <td>⭐ 15</td>
876
+ <td>⭐ 19</td>
853
877
  </tr>
854
878
  </table>
855
879
 
@@ -1,33 +1,35 @@
1
- mcp_use/__init__.py,sha256=I3gFxw6Id45RksUBIZS1kxBW3ItjFXuAfoReJabpnW0,1055
2
- mcp_use/client.py,sha256=dziKHIZIclLk64ycF4keegiVp93YKqSyGok7Rv4j8bE,10958
3
- mcp_use/config.py,sha256=J3ebF9dlQxui3pSONTFtVYO035E7d0CP4HAvN0INgE4,3103
1
+ mcp_use/__init__.py,sha256=vyjxKmfVDtkbJ6sthDEH_m-uJGXxkYdUBMwBpCt72zA,1021
2
+ mcp_use/client.py,sha256=4WnFrbBBa3YX3brfBgZrhb_OgAT8mMfVzLUHwnnKi8o,11701
3
+ mcp_use/config.py,sha256=yRgUPCMUzkFqROyccG2wjuhGxneCcbgnrHWHQ6z_hoc,3487
4
4
  mcp_use/logging.py,sha256=CRtkPwR-bkXK_kQ0QOL86RikMWOHzEOi7A8VRHkNsZw,4270
5
- mcp_use/session.py,sha256=4kwcB_IkTt_3FiBSTI1H17KhL1W_6N5oai3HTxFrTH4,2496
5
+ mcp_use/session.py,sha256=DpH_z0a3xYemV9yWzlrf-IPZtpR27CI2S-gAm2jbCAc,4700
6
6
  mcp_use/utils.py,sha256=QavJcVq2WxUUUCCpPCUeOB5bqIS0FFmpK-RAZkGc6aA,720
7
7
  mcp_use/adapters/__init__.py,sha256=-xCrgPThuX7x0PHGFDdjb7M-mgw6QV3sKu5PM7ShnRg,275
8
- mcp_use/adapters/base.py,sha256=U1z_UzojC-bytb4ZuKTRpEgEp-2F_BVBgqEXbUqLYB4,6901
9
- mcp_use/adapters/langchain_adapter.py,sha256=LdlpRyLORhl8NZvtAmisgPelXkhEbBErSNdGHb8SF18,10860
8
+ mcp_use/adapters/base.py,sha256=8XB3xWZ6nJPhhmHwVtHT8-HO0D_9nnxzOkbVDP-fI3k,6940
9
+ mcp_use/adapters/langchain_adapter.py,sha256=zGEVMXLj_jpSXUMHOh5u-fxkkrK2zpSibOSGCy_VMr0,11033
10
10
  mcp_use/agents/__init__.py,sha256=FzkntihbAqzixWdWe99zIrrcIfd4N3YWltNniutG9VA,267
11
11
  mcp_use/agents/base.py,sha256=EN-dRbwOi9vIqofFg3jmi5yT2VKlwEr9Cwi1DZgB3eE,1591
12
12
  mcp_use/agents/mcpagent.py,sha256=Vh4VOxxh-6sJwK1tTtJgUWZcp1bd3hb_JnATc7x9sKk,46698
13
- mcp_use/agents/remote.py,sha256=_8TKP-hfr8NsexbpaEz8bK4LU-opILJMnTL7TbQBiY4,10575
13
+ mcp_use/agents/remote.py,sha256=peSw3aixybneTWgrGlSZedUvo_FuISSiWqFgySZSwEM,13011
14
14
  mcp_use/agents/prompts/system_prompt_builder.py,sha256=E86STmxcl2Ic763_114awNqFB2RyLrQlbvgRmJajQjI,4116
15
15
  mcp_use/agents/prompts/templates.py,sha256=acg2Q-_uQDL-3q5ZUwwwFrP7wqqf-SEyq0XWDDHt69s,1906
16
16
  mcp_use/connectors/__init__.py,sha256=cUF4yT0bNr8qeLkSzg28SHueiV5qDaHEB1l1GZ2K0dc,536
17
- mcp_use/connectors/base.py,sha256=bCPOrSb3xzuxQRFpcLf7tCG1UmMFtr9IVM7br8JlbzI,13878
18
- mcp_use/connectors/http.py,sha256=8LVzXtVtdLVQH9xMIqPzKfPEmaO_cxzMIu4g4oGIung,7912
19
- mcp_use/connectors/sandbox.py,sha256=RX8xssn0cIObW6CjOqY7ZrO_D9lTzCZKdRcJ5lQSmQg,11441
20
- mcp_use/connectors/stdio.py,sha256=jTNhrsHxkRgSI9uAnj4bbFsBwe6zooc-oNcMXV_s9Xk,3378
17
+ mcp_use/connectors/base.py,sha256=R1Qh9D6btullQUGiMBVZewP3M7d-0VrsIt4bSw3bHxI,17482
18
+ mcp_use/connectors/http.py,sha256=eiX5NAsT9mnzqWRAoxb6qG3nWxPiVyw5MVcwRY8D6lE,8436
19
+ mcp_use/connectors/sandbox.py,sha256=oXs4Q_1bQJ10XOrJLjFUBKvFy2VmWmyzLhotczl44Po,11804
20
+ mcp_use/connectors/stdio.py,sha256=4gXdXyaeA3B-ywAjPmbEEbHxP2Gg5cWsXNC2kHkubDA,3766
21
21
  mcp_use/connectors/utils.py,sha256=zQ8GdNQx0Twz3by90BoU1RsWPf9wODGof4K3-NxPXeA,366
22
22
  mcp_use/connectors/websocket.py,sha256=G7ZeLJNPVl9AG6kCmiNJz1N2Ing_QxT7pSswigTKi8Y,9650
23
+ mcp_use/errors/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
24
+ mcp_use/errors/error_formatting.py,sha256=17lhj5goGHuTbJ5oLCUXyJ2SuIbzsuSM1Wk8LPeqY9k,911
23
25
  mcp_use/managers/__init__.py,sha256=FRTuJw5kYtY1Eo7wN9Aeqeqo1euiR5slvrx5Fl_SGvk,383
24
- mcp_use/managers/server_manager.py,sha256=8F6jEwZOoAfR1y1O7zk-BSZ1LVYcLZTSQZLRClhSE2I,5278
26
+ mcp_use/managers/server_manager.py,sha256=eWxiuP0yL3HWSyCWdHqNZ1isZfa3IZDWVEjWSfYOs_A,5253
25
27
  mcp_use/managers/tools/__init__.py,sha256=zcpm4HXsp8NUMRJeyT6DdB8cgIMDs46pBfoTD-odhGU,437
26
28
  mcp_use/managers/tools/base_tool.py,sha256=Jbbp7SwmHKDk8jT_6yVIv7iNsn6KaV_PljWuhhLcbXg,509
27
- mcp_use/managers/tools/connect_server.py,sha256=MGYQCl11q-w6gSIYuT44dDk7ILV3Oh7kGAJ4fsNXbso,2923
28
- mcp_use/managers/tools/disconnect_server.py,sha256=Y3kJN31efzsjfJwxUhpBxS-bgU21DCfGbn_LgEbzyvI,1586
29
+ mcp_use/managers/tools/connect_server.py,sha256=-PlqgJDSMzairK90aDg1WTDjpqrFMoTiyekwoPDWNrw,2964
30
+ mcp_use/managers/tools/disconnect_server.py,sha256=dLa5PH-QZ30Dw3n5lzqilyHA8PuQ6xvMkXd-T5EwpU8,1622
29
31
  mcp_use/managers/tools/get_active_server.py,sha256=tCaib76gYU3L5G82tEOTq4Io2cuCXWjOjPselb-92i8,964
30
- mcp_use/managers/tools/list_servers_tool.py,sha256=OPDSMNe-VuAhlUyhDnR4CiuZFpoMhnhWpAablwO5S0k,1897
32
+ mcp_use/managers/tools/list_servers_tool.py,sha256=P_Z96Ab8ELLyo3GQfTMfyemTPJwt0VR1s_iMnWE1GCg,2037
31
33
  mcp_use/managers/tools/search_tools.py,sha256=4vso7ln-AfG6lQAMq9FA_CyeVtSEDYEWlHtdHtfnLps,12911
32
34
  mcp_use/observability/__init__.py,sha256=kTUcP0d6L5_3ktfldhdAk-3AWckzVHs7ztG-R6cye64,186
33
35
  mcp_use/observability/laminar.py,sha256=WWjmVXP55yCfAlqlayeuJmym1gdrv8is7UyrIp4Tbn0,839
@@ -40,10 +42,10 @@ mcp_use/task_managers/streamable_http.py,sha256=Zky821Ston5CX0DQVyeRxc2uUqALD8so
40
42
  mcp_use/task_managers/websocket.py,sha256=9JTw705rhYbP6x2xAPF6PwtNgF5yEWTQhx-dYSPMoaI,2154
41
43
  mcp_use/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
44
  mcp_use/telemetry/events.py,sha256=K5xqbmkum30r4gM2PWtTiUWGF8oZzGZw2DYwco1RfOQ,3113
43
- mcp_use/telemetry/telemetry.py,sha256=ck2MDFMtooafriR1W_zi41dWq-0O-ucF89pCkdkyc9E,11724
45
+ mcp_use/telemetry/telemetry.py,sha256=oM_QAbZwOStKkeccvEfKmJLKhL2neFkPn5yM5rL2qHc,11711
44
46
  mcp_use/telemetry/utils.py,sha256=kDVTqt2oSeWNJbnTOlXOehr2yFO0PMyx2UGkrWkfJiw,1769
45
47
  mcp_use/types/sandbox.py,sha256=opJ9r56F1FvaqVvPovfAj5jZbsOexgwYx5wLgSlN8_U,712
46
- mcp_use-1.3.8.dist-info/METADATA,sha256=nqKWqFTWM-XqfsPrXXyn5Q6opaMyWz_oe3qfSZEfM3M,30356
47
- mcp_use-1.3.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
48
- mcp_use-1.3.8.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
49
- mcp_use-1.3.8.dist-info/RECORD,,
48
+ mcp_use-1.3.9.dist-info/METADATA,sha256=U-uwkjLkdcK1IkliQ6UGY_jKRUJEgN1K_2xQEHTB9Yk,34122
49
+ mcp_use-1.3.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
+ mcp_use-1.3.9.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
51
+ mcp_use-1.3.9.dist-info/RECORD,,