mcp-use 1.0.0__py3-none-any.whl → 1.0.1__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/config.py CHANGED
@@ -43,9 +43,9 @@ def create_connector_from_config(server_config: dict[str, Any]) -> BaseConnector
43
43
  # HTTP connector
44
44
  elif "url" in server_config:
45
45
  return HttpConnector(
46
- url=server_config["url"],
46
+ base_url=server_config["url"],
47
47
  headers=server_config.get("headers", None),
48
- auth=server_config.get("auth", None),
48
+ auth_token=server_config.get("auth_token", None),
49
49
  )
50
50
 
51
51
  # WebSocket connector
@@ -53,7 +53,7 @@ def create_connector_from_config(server_config: dict[str, Any]) -> BaseConnector
53
53
  return WebSocketConnector(
54
54
  url=server_config["ws_url"],
55
55
  headers=server_config.get("headers", None),
56
- auth=server_config.get("auth", None),
56
+ auth_token=server_config.get("auth_token", None),
57
57
  )
58
58
 
59
59
  raise ValueError("Cannot determine connector type from config")
@@ -8,8 +8,12 @@ must implement.
8
8
  from abc import ABC, abstractmethod
9
9
  from typing import Any
10
10
 
11
+ from mcp import ClientSession
11
12
  from mcp.types import CallToolResult, Tool
12
13
 
14
+ from ..logging import logger
15
+ from ..task_managers import ConnectionManager
16
+
13
17
 
14
18
  class BaseConnector(ABC):
15
19
  """Base class for MCP connectors.
@@ -17,43 +21,119 @@ class BaseConnector(ABC):
17
21
  This class defines the interface that all MCP connectors must implement.
18
22
  """
19
23
 
24
+ def __init__(self):
25
+ """Initialize base connector with common attributes."""
26
+ self.client: ClientSession | None = None
27
+ self._connection_manager: ConnectionManager | None = None
28
+ self._tools: list[Tool] | None = None
29
+ self._connected = False
30
+
20
31
  @abstractmethod
21
32
  async def connect(self) -> None:
22
33
  """Establish a connection to the MCP implementation."""
23
34
  pass
24
35
 
25
- @abstractmethod
26
36
  async def disconnect(self) -> None:
27
37
  """Close the connection to the MCP implementation."""
28
- pass
38
+ if not self._connected:
39
+ logger.debug("Not connected to MCP implementation")
40
+ return
41
+
42
+ logger.info("Disconnecting from MCP implementation")
43
+ await self._cleanup_resources()
44
+ self._connected = False
45
+ logger.info("Disconnected from MCP implementation")
46
+
47
+ async def _cleanup_resources(self) -> None:
48
+ """Clean up all resources associated with this connector."""
49
+ errors = []
50
+
51
+ # First close the client session
52
+ if self.client:
53
+ try:
54
+ logger.debug("Closing client session")
55
+ await self.client.__aexit__(None, None, None)
56
+ except Exception as e:
57
+ error_msg = f"Error closing client session: {e}"
58
+ logger.warning(error_msg)
59
+ errors.append(error_msg)
60
+ finally:
61
+ self.client = None
62
+
63
+ # Then stop the connection manager
64
+ if self._connection_manager:
65
+ try:
66
+ logger.debug("Stopping connection manager")
67
+ await self._connection_manager.stop()
68
+ except Exception as e:
69
+ error_msg = f"Error stopping connection manager: {e}"
70
+ logger.warning(error_msg)
71
+ errors.append(error_msg)
72
+ finally:
73
+ self._connection_manager = None
74
+
75
+ # Reset tools
76
+ self._tools = None
77
+
78
+ if errors:
79
+ logger.warning(f"Encountered {len(errors)} errors during resource cleanup")
29
80
 
30
- @abstractmethod
31
81
  async def initialize(self) -> dict[str, Any]:
32
82
  """Initialize the MCP session and return session information."""
33
- pass
83
+ if not self.client:
84
+ raise RuntimeError("MCP client is not connected")
85
+
86
+ logger.info("Initializing MCP session")
87
+
88
+ # Initialize the session
89
+ result = await self.client.initialize()
90
+
91
+ # Get available tools
92
+ tools_result = await self.client.list_tools()
93
+ self._tools = tools_result.tools
94
+
95
+ logger.info(f"MCP session initialized with {len(self._tools)} tools")
96
+
97
+ return result
34
98
 
35
99
  @property
36
- @abstractmethod
37
100
  def tools(self) -> list[Tool]:
38
101
  """Get the list of available tools."""
39
- pass
102
+ if not self._tools:
103
+ raise RuntimeError("MCP client is not initialized")
104
+ return self._tools
40
105
 
41
- @abstractmethod
42
106
  async def call_tool(self, name: str, arguments: dict[str, Any]) -> CallToolResult:
43
107
  """Call an MCP tool with the given arguments."""
44
- pass
108
+ if not self.client:
109
+ raise RuntimeError("MCP client is not connected")
110
+
111
+ logger.debug(f"Calling tool '{name}' with arguments: {arguments}")
112
+ result = await self.client.call_tool(name, arguments)
113
+ return result
45
114
 
46
- @abstractmethod
47
115
  async def list_resources(self) -> list[dict[str, Any]]:
48
116
  """List all available resources from the MCP implementation."""
49
- pass
117
+ if not self.client:
118
+ raise RuntimeError("MCP client is not connected")
119
+
120
+ logger.debug("Listing resources")
121
+ resources = await self.client.list_resources()
122
+ return resources
50
123
 
51
- @abstractmethod
52
124
  async def read_resource(self, uri: str) -> tuple[bytes, str]:
53
125
  """Read a resource by URI."""
54
- pass
126
+ if not self.client:
127
+ raise RuntimeError("MCP client is not connected")
128
+
129
+ logger.debug(f"Reading resource: {uri}")
130
+ resource = await self.client.read_resource(uri)
131
+ return resource.content, resource.mimeType
55
132
 
56
- @abstractmethod
57
133
  async def request(self, method: str, params: dict[str, Any] | None = None) -> Any:
58
134
  """Send a raw request to the MCP implementation."""
59
- pass
135
+ if not self.client:
136
+ raise RuntimeError("MCP client is not connected")
137
+
138
+ logger.debug(f"Sending request: {method} with params: {params}")
139
+ return await self.client.request({"method": method, "params": params or {}})
@@ -2,23 +2,20 @@
2
2
  HTTP connector for MCP implementations.
3
3
 
4
4
  This module provides a connector for communicating with MCP implementations
5
- through HTTP APIs.
5
+ through HTTP APIs with SSE for transport.
6
6
  """
7
7
 
8
- from typing import Any
9
-
10
- import aiohttp
11
- from mcp.types import Tool
8
+ from mcp import ClientSession
12
9
 
13
10
  from ..logging import logger
14
- from ..task_managers import ConnectionManager, HttpConnectionManager
11
+ from ..task_managers import SseConnectionManager
15
12
  from .base import BaseConnector
16
13
 
17
14
 
18
15
  class HttpConnector(BaseConnector):
19
- """Connector for MCP implementations using HTTP transport.
16
+ """Connector for MCP implementations using HTTP transport with SSE.
20
17
 
21
- This connector uses HTTP requests to communicate with remote MCP implementations,
18
+ This connector uses HTTP/SSE to communicate with remote MCP implementations,
22
19
  using a connection manager to handle the proper lifecycle management.
23
20
  """
24
21
 
@@ -27,6 +24,8 @@ class HttpConnector(BaseConnector):
27
24
  base_url: str,
28
25
  auth_token: str | None = None,
29
26
  headers: dict[str, str] | None = None,
27
+ timeout: float = 5,
28
+ sse_read_timeout: float = 60 * 5,
30
29
  ):
31
30
  """Initialize a new HTTP connector.
32
31
 
@@ -34,17 +33,17 @@ class HttpConnector(BaseConnector):
34
33
  base_url: The base URL of the MCP HTTP API.
35
34
  auth_token: Optional authentication token.
36
35
  headers: Optional additional headers.
36
+ timeout: Timeout for HTTP operations in seconds.
37
+ sse_read_timeout: Timeout for SSE read operations in seconds.
37
38
  """
39
+ super().__init__()
38
40
  self.base_url = base_url.rstrip("/")
39
41
  self.auth_token = auth_token
40
42
  self.headers = headers or {}
41
43
  if auth_token:
42
44
  self.headers["Authorization"] = f"Bearer {auth_token}"
43
-
44
- self.session: aiohttp.ClientSession | None = None
45
- self._connection_manager: ConnectionManager | None = None
46
- self._tools: list[Tool] | None = None
47
- self._connected = False
45
+ self.timeout = timeout
46
+ self.sse_read_timeout = sse_read_timeout
48
47
 
49
48
  async def connect(self) -> None:
50
49
  """Establish a connection to the MCP implementation."""
@@ -52,159 +51,32 @@ class HttpConnector(BaseConnector):
52
51
  logger.debug("Already connected to MCP implementation")
53
52
  return
54
53
 
55
- logger.info(f"Connecting to MCP implementation via HTTP: {self.base_url}")
54
+ logger.info(f"Connecting to MCP implementation via HTTP/SSE: {self.base_url}")
56
55
  try:
56
+ # Create the SSE connection URL
57
+ sse_url = f"{self.base_url}/sse"
58
+
57
59
  # Create and start the connection manager
58
- self._connection_manager = HttpConnectionManager(self.base_url, self.headers)
59
- self.session = await self._connection_manager.start()
60
+ self._connection_manager = SseConnectionManager(
61
+ sse_url, self.headers, self.timeout, self.sse_read_timeout
62
+ )
63
+ read_stream, write_stream = await self._connection_manager.start()
64
+
65
+ # Create the client session
66
+ self.client = ClientSession(read_stream, write_stream, sampling_callback=None)
67
+ await self.client.__aenter__()
60
68
 
61
69
  # Mark as connected
62
70
  self._connected = True
63
- logger.info(f"Successfully connected to MCP implementation via HTTP: {self.base_url}")
71
+ logger.info(
72
+ f"Successfully connected to MCP implementation via HTTP/SSE: {self.base_url}"
73
+ )
64
74
 
65
75
  except Exception as e:
66
- logger.error(f"Failed to connect to MCP implementation via HTTP: {e}")
76
+ logger.error(f"Failed to connect to MCP implementation via HTTP/SSE: {e}")
67
77
 
68
78
  # Clean up any resources if connection failed
69
79
  await self._cleanup_resources()
70
80
 
71
81
  # Re-raise the original exception
72
82
  raise
73
-
74
- async def disconnect(self) -> None:
75
- """Close the connection to the MCP implementation."""
76
- if not self._connected:
77
- logger.debug("Not connected to MCP implementation")
78
- return
79
-
80
- logger.info("Disconnecting from MCP implementation")
81
- await self._cleanup_resources()
82
- self._connected = False
83
- logger.info("Disconnected from MCP implementation")
84
-
85
- async def _cleanup_resources(self) -> None:
86
- """Clean up all resources associated with this connector."""
87
- errors = []
88
-
89
- # Stop the connection manager
90
- if self._connection_manager:
91
- try:
92
- logger.debug("Stopping connection manager")
93
- await self._connection_manager.stop()
94
- except Exception as e:
95
- error_msg = f"Error stopping connection manager: {e}"
96
- logger.warning(error_msg)
97
- errors.append(error_msg)
98
- finally:
99
- self._connection_manager = None
100
- self.session = None
101
-
102
- # Reset tools
103
- self._tools = None
104
-
105
- if errors:
106
- logger.warning(f"Encountered {len(errors)} errors during resource cleanup")
107
-
108
- async def _request(self, method: str, endpoint: str, data: dict[str, Any] | None = None) -> Any:
109
- """Send an HTTP request to the MCP API.
110
-
111
- Args:
112
- method: The HTTP method (GET, POST, etc.).
113
- endpoint: The API endpoint path.
114
- data: Optional request data.
115
-
116
- Returns:
117
- The parsed JSON response.
118
- """
119
- if not self.session:
120
- raise RuntimeError("HTTP session is not connected")
121
-
122
- url = f"{self.base_url}/{endpoint.lstrip('/')}"
123
- logger.debug(f"Sending {method} request to {url}")
124
-
125
- if method.upper() == "GET" and data:
126
- # For GET requests, convert data to query parameters
127
- async with self.session.get(url, params=data) as response:
128
- response.raise_for_status()
129
- return await response.json()
130
- else:
131
- # For other methods, send data as JSON body
132
- async with self.session.request(method, url, json=data) as response:
133
- response.raise_for_status()
134
- return await response.json()
135
-
136
- async def initialize(self) -> dict[str, Any]:
137
- """Initialize the MCP session and return session information."""
138
- logger.info("Initializing MCP session")
139
-
140
- # Initialize the session
141
- result = await self._request("POST", "initialize")
142
-
143
- # Get available tools
144
- tools_result = await self.list_tools()
145
- self._tools = [Tool(**tool) for tool in tools_result]
146
-
147
- logger.info(f"MCP session initialized with {len(self._tools)} tools")
148
- return result
149
-
150
- async def list_tools(self) -> list[dict[str, Any]]:
151
- """List all available tools from the MCP implementation."""
152
- logger.debug("Listing tools")
153
- result = await self._request("GET", "tools")
154
- return result.get("tools", [])
155
-
156
- @property
157
- def tools(self) -> list[Tool]:
158
- """Get the list of available tools."""
159
- if not self._tools:
160
- raise RuntimeError("MCP client is not initialized")
161
- return self._tools
162
-
163
- async def call_tool(self, name: str, arguments: dict[str, Any]) -> Any:
164
- """Call an MCP tool with the given arguments."""
165
- logger.debug(f"Calling tool '{name}' with arguments: {arguments}")
166
- return await self._request("POST", f"tools/{name}", arguments)
167
-
168
- async def list_resources(self) -> list[dict[str, Any]]:
169
- """List all available resources from the MCP implementation."""
170
- logger.debug("Listing resources")
171
- result = await self._request("GET", "resources")
172
- return result
173
-
174
- async def read_resource(self, uri: str) -> tuple[bytes, str]:
175
- """Read a resource by URI."""
176
- logger.debug(f"Reading resource: {uri}")
177
-
178
- # For resources, we may need to handle binary data
179
- if not self.session:
180
- raise RuntimeError("HTTP session is not connected")
181
-
182
- url = f"{self.base_url}/resources/read"
183
-
184
- async with self.session.get(url, params={"uri": uri}) as response:
185
- response.raise_for_status()
186
-
187
- # Check if this is a JSON response or binary data
188
- content_type = response.headers.get("Content-Type", "")
189
- if "application/json" in content_type:
190
- data = await response.json()
191
- content = data.get("content", b"")
192
- mime_type = data.get("mimeType", "")
193
-
194
- # If content is base64 encoded, decode it
195
- if isinstance(content, str):
196
- import base64
197
-
198
- content = base64.b64decode(content)
199
-
200
- return content, mime_type
201
- else:
202
- # Assume binary response
203
- content = await response.read()
204
- return content, content_type
205
-
206
- async def request(self, method: str, params: dict[str, Any] | None = None) -> Any:
207
- """Send a raw request to the MCP implementation."""
208
- logger.debug(f"Sending request: {method} with params: {params}")
209
- # For custom methods, we'll use the RPC-style endpoint
210
- return await self._request("POST", "rpc", {"method": method, "params": params or {}})
@@ -6,13 +6,11 @@ through the standard input/output streams.
6
6
  """
7
7
 
8
8
  import sys
9
- from typing import Any
10
9
 
11
10
  from mcp import ClientSession, StdioServerParameters
12
- from mcp.types import CallToolResult, Tool
13
11
 
14
12
  from ..logging import logger
15
- from ..task_managers import ConnectionManager, StdioConnectionManager
13
+ from ..task_managers import StdioConnectionManager
16
14
  from .base import BaseConnector
17
15
 
18
16
 
@@ -39,14 +37,11 @@ class StdioConnector(BaseConnector):
39
37
  env: Optional environment variables.
40
38
  errlog: Stream to write error output to.
41
39
  """
40
+ super().__init__()
42
41
  self.command = command
43
42
  self.args = args or [] # Ensure args is never None
44
43
  self.env = env
45
44
  self.errlog = errlog
46
- self.client: ClientSession | None = None
47
- self._connection_manager: ConnectionManager | None = None
48
- self._tools: list[Tool] | None = None
49
- self._connected = False
50
45
 
51
46
  async def connect(self) -> None:
52
47
  """Establish a connection to the MCP implementation."""
@@ -81,108 +76,3 @@ class StdioConnector(BaseConnector):
81
76
 
82
77
  # Re-raise the original exception
83
78
  raise
84
-
85
- async def disconnect(self) -> None:
86
- """Close the connection to the MCP implementation."""
87
- if not self._connected:
88
- logger.debug("Not connected to MCP implementation")
89
- return
90
-
91
- logger.info("Disconnecting from MCP implementation")
92
- await self._cleanup_resources()
93
- self._connected = False
94
- logger.info("Disconnected from MCP implementation")
95
-
96
- async def _cleanup_resources(self) -> None:
97
- """Clean up all resources associated with this connector."""
98
- errors = []
99
-
100
- # First close the client session
101
- if self.client:
102
- try:
103
- logger.debug("Closing client session")
104
- await self.client.__aexit__(None, None, None)
105
- except Exception as e:
106
- error_msg = f"Error closing client session: {e}"
107
- logger.warning(error_msg)
108
- errors.append(error_msg)
109
- finally:
110
- self.client = None
111
-
112
- # Then stop the connection manager
113
- if self._connection_manager:
114
- try:
115
- logger.debug("Stopping connection manager")
116
- await self._connection_manager.stop()
117
- except Exception as e:
118
- error_msg = f"Error stopping connection manager: {e}"
119
- logger.warning(error_msg)
120
- errors.append(error_msg)
121
- finally:
122
- self._connection_manager = None
123
-
124
- # Reset tools
125
- self._tools = None
126
-
127
- if errors:
128
- logger.warning(f"Encountered {len(errors)} errors during resource cleanup")
129
-
130
- async def initialize(self) -> dict[str, Any]:
131
- """Initialize the MCP session and return session information."""
132
- if not self.client:
133
- raise RuntimeError("MCP client is not connected")
134
-
135
- logger.info("Initializing MCP session")
136
-
137
- # Initialize the session
138
- result = await self.client.initialize()
139
-
140
- # Get available tools
141
- tools_result = await self.client.list_tools()
142
- self._tools = tools_result.tools
143
-
144
- logger.info(f"MCP session initialized with {len(self._tools)} tools")
145
-
146
- return result
147
-
148
- @property
149
- def tools(self) -> list[Tool]:
150
- """Get the list of available tools."""
151
- if not self._tools:
152
- raise RuntimeError("MCP client is not initialized")
153
- return self._tools
154
-
155
- async def call_tool(self, name: str, arguments: dict[str, Any]) -> CallToolResult:
156
- """Call an MCP tool with the given arguments."""
157
- if not self.client:
158
- raise RuntimeError("MCP client is not connected")
159
-
160
- logger.debug(f"Calling tool '{name}' with arguments: {arguments}")
161
- result = await self.client.call_tool(name, arguments)
162
- return result
163
-
164
- async def list_resources(self) -> list[dict[str, Any]]:
165
- """List all available resources from the MCP implementation."""
166
- if not self.client:
167
- raise RuntimeError("MCP client is not connected")
168
-
169
- logger.debug("Listing resources")
170
- resources = await self.client.list_resources()
171
- return resources
172
-
173
- async def read_resource(self, uri: str) -> tuple[bytes, str]:
174
- """Read a resource by URI."""
175
- if not self.client:
176
- raise RuntimeError("MCP client is not connected")
177
-
178
- logger.debug(f"Reading resource: {uri}")
179
- resource = await self.client.read_resource(uri)
180
- return resource.content, resource.mimeType
181
-
182
- async def request(self, method: str, params: dict[str, Any] | None = None) -> Any:
183
- """Send a raw request to the MCP implementation."""
184
- if not self.client:
185
- raise RuntimeError("MCP client is not connected")
186
-
187
- logger.debug(f"Sending request: {method} with params: {params}")
188
- return await self.client.request({"method": method, "params": params or {}})
@@ -6,7 +6,7 @@ through different transport mechanisms.
6
6
  """
7
7
 
8
8
  from .base import ConnectionManager
9
- from .http import HttpConnectionManager
9
+ from .sse import SseConnectionManager
10
10
  from .stdio import StdioConnectionManager
11
11
  from .websocket import WebSocketConnectionManager
12
12
 
@@ -15,4 +15,5 @@ __all__ = [
15
15
  "HttpConnectionManager",
16
16
  "StdioConnectionManager",
17
17
  "WebSocketConnectionManager",
18
+ "SseConnectionManager",
18
19
  ]
@@ -0,0 +1,82 @@
1
+ """
2
+ SSE connection management for MCP implementations.
3
+
4
+ This module provides a connection manager for SSE-based MCP connections
5
+ that ensures proper task isolation and resource cleanup.
6
+ """
7
+
8
+ from typing import Any
9
+
10
+ from mcp.client.sse import sse_client
11
+
12
+ from ..logging import logger
13
+ from .base import ConnectionManager
14
+
15
+
16
+ class SseConnectionManager(ConnectionManager[tuple[Any, Any]]):
17
+ """Connection manager for SSE-based MCP connections.
18
+
19
+ This class handles the proper task isolation for sse_client context managers
20
+ to prevent the "cancel scope in different task" error. It runs the sse_client
21
+ in a dedicated task and manages its lifecycle.
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ url: str,
27
+ headers: dict[str, str] | None = None,
28
+ timeout: float = 5,
29
+ sse_read_timeout: float = 60 * 5,
30
+ ):
31
+ """Initialize a new SSE connection manager.
32
+
33
+ Args:
34
+ url: The SSE endpoint URL
35
+ headers: Optional HTTP headers
36
+ timeout: Timeout for HTTP operations in seconds
37
+ sse_read_timeout: Timeout for SSE read operations in seconds
38
+ """
39
+ super().__init__()
40
+ self.url = url
41
+ self.headers = headers or {}
42
+ self.timeout = timeout
43
+ self.sse_read_timeout = sse_read_timeout
44
+ self._sse_ctx = None
45
+
46
+ async def _establish_connection(self) -> tuple[Any, Any]:
47
+ """Establish an SSE connection.
48
+
49
+ Returns:
50
+ A tuple of (read_stream, write_stream)
51
+
52
+ Raises:
53
+ Exception: If connection cannot be established.
54
+ """
55
+ # Create the context manager
56
+ self._sse_ctx = sse_client(
57
+ url=self.url,
58
+ headers=self.headers,
59
+ timeout=self.timeout,
60
+ sse_read_timeout=self.sse_read_timeout,
61
+ )
62
+
63
+ # Enter the context manager
64
+ read_stream, write_stream = await self._sse_ctx.__aenter__()
65
+
66
+ # Return the streams
67
+ return (read_stream, write_stream)
68
+
69
+ async def _close_connection(self, connection: tuple[Any, Any]) -> None:
70
+ """Close the SSE connection.
71
+
72
+ Args:
73
+ connection: The connection to close (ignored, we use the context manager)
74
+ """
75
+ if self._sse_ctx:
76
+ # Exit the context manager
77
+ try:
78
+ await self._sse_ctx.__aexit__(None, None, None)
79
+ except Exception as e:
80
+ logger.warning(f"Error closing SSE context: {e}")
81
+ finally:
82
+ self._sse_ctx = None
@@ -5,13 +5,13 @@ This module provides a connection manager for WebSocket-based MCP connections.
5
5
  """
6
6
 
7
7
  import websockets
8
- from websockets.client import WebSocketClientProtocol
8
+ from websockets.client import ClientConnection
9
9
 
10
10
  from ..logging import logger
11
11
  from .base import ConnectionManager
12
12
 
13
13
 
14
- class WebSocketConnectionManager(ConnectionManager[WebSocketClientProtocol]):
14
+ class WebSocketConnectionManager(ConnectionManager[ClientConnection]):
15
15
  """Connection manager for WebSocket-based MCP connections.
16
16
 
17
17
  This class handles the lifecycle of WebSocket connections, ensuring proper
@@ -33,7 +33,7 @@ class WebSocketConnectionManager(ConnectionManager[WebSocketClientProtocol]):
33
33
  self.url = url
34
34
  self.headers = headers or {}
35
35
 
36
- async def _establish_connection(self) -> WebSocketClientProtocol:
36
+ async def _establish_connection(self) -> ClientConnection:
37
37
  """Establish a WebSocket connection.
38
38
 
39
39
  Returns:
@@ -50,7 +50,7 @@ class WebSocketConnectionManager(ConnectionManager[WebSocketClientProtocol]):
50
50
  logger.error(f"Failed to connect to WebSocket: {e}")
51
51
  raise
52
52
 
53
- async def _close_connection(self, connection: WebSocketClientProtocol) -> None:
53
+ async def _close_connection(self, connection: ClientConnection) -> None:
54
54
  """Close the WebSocket connection.
55
55
 
56
56
  Args:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-use
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: MCP Library for LLMs
5
5
  Author-email: Pietro Zullo <pietro.zullo@gmail.com>
6
6
  License: MIT
@@ -38,7 +38,7 @@ Requires-Dist: openai>=1.10.0; extra == 'openai'
38
38
  Description-Content-Type: text/markdown
39
39
 
40
40
  <picture>
41
- <img alt="" src="./static/mcpusegrass.png" width="full">
41
+ <img alt="" src="./static/image.jpg" width="full">
42
42
  </picture>
43
43
 
44
44
  <h1 align="center">Open Source MCP CLient Library </h1>
@@ -47,6 +47,7 @@ Description-Content-Type: text/markdown
47
47
  [![PyPI Downloads](https://img.shields.io/pypi/dm/mcp_use.svg)](https://pypi.org/project/mcp_use/)
48
48
  [![PyPI Version](https://img.shields.io/pypi/v/mcp_use.svg)](https://pypi.org/project/mcp_use/)
49
49
  [![Python Versions](https://img.shields.io/pypi/pyversions/mcp_use.svg)](https://pypi.org/project/mcp_use/)
50
+ [![Documentation](https://img.shields.io/badge/docs-mcp--use.io-blue)](https://docs.mcp-use.io)
50
51
  [![License](https://img.shields.io/github/license/pietrozullo/mcp-use)](https://github.com/pietrozullo/mcp-use/blob/main/LICENSE)
51
52
  [![Code style: Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
52
53
  [![GitHub stars](https://img.shields.io/github/stars/pietrozullo/mcp-use?style=social)](https://github.com/pietrozullo/mcp-use/stargazers)
@@ -1,6 +1,6 @@
1
1
  mcp_use/__init__.py,sha256=PSoxLAu1GPjfIDPcZiJyI3k66MMS3lcfx5kERUgFb1o,723
2
2
  mcp_use/client.py,sha256=0rvlJBwvPD19sjDRtXfnp15-F1VHJlXWxLQNt9cHwPA,8275
3
- mcp_use/config.py,sha256=D9LuCuT1mFUSBiO2DUGa5Pnd-yjNcvM9u_v11N5UmK8,1624
3
+ mcp_use/config.py,sha256=O9V4pa-shZ2mPokRTrd7KZQ2GpuTcYBGUslefl1fosw,1653
4
4
  mcp_use/logging.py,sha256=2-hSB7ZWcHEx_OFHNg8GIbSGCZx3MW4mZGGWxi2Ew3E,2690
5
5
  mcp_use/session.py,sha256=Z4EZTUnQUX0QyGMzkJIrMRTX4SDk6qQUoBld408LIJE,3449
6
6
  mcp_use/agents/__init__.py,sha256=ukchMTqCOID6ikvLmJ-6sldWTVFIzztGQo4BX6QeQr8,312
@@ -9,16 +9,16 @@ mcp_use/agents/langchain_agent.py,sha256=q6zIb9J9fc15HRGDjPAhmPdM_8UOqQToy8ESeyr
9
9
  mcp_use/agents/mcpagent.py,sha256=lTRutdT1QIMiTbMSKfSbqlqNq_Y6uDPfkjAzJAKb6H0,12727
10
10
  mcp_use/agents/prompts/default.py,sha256=tnwt9vOiVBhdpu-lIHhwEJo3rvE6EobPfUgS9JURBzg,941
11
11
  mcp_use/connectors/__init__.py,sha256=jnd-7pPPJMb0UNJ6aD9lInj5Tlamc8lA_mFyG8RWJpo,385
12
- mcp_use/connectors/base.py,sha256=caUaTfsODUOik8JF9mPtcZDyZhoIz2X12I_BhAfZK10,1616
13
- mcp_use/connectors/http.py,sha256=KqVf0HXouFoeQ_bBUr6KQifiUjTo7K6EOCRkqVpFx4Q,7763
14
- mcp_use/connectors/stdio.py,sha256=aEeZ-OZS6yknFPEy-YpwvwFILGIaAsA48uB1I4j8wog,6752
12
+ mcp_use/connectors/base.py,sha256=TCLVNJdt6qrflmphgXOZhD6xPKQQegbGqe5REmcLYg0,4813
13
+ mcp_use/connectors/http.py,sha256=vNrVOjO_7SLJv_G6Gio3moRu11omKY6nM3_34yUMpew,2839
14
+ mcp_use/connectors/stdio.py,sha256=36yEY7hbFXgM7zju5BtLJl4cKAZNCXVRrTaU6YOttBI,2606
15
15
  mcp_use/connectors/websocket.py,sha256=4xqxl9UncrfU6NitvKfB80Hk2g7o0Gc0G5sm6sY3RAk,9534
16
- mcp_use/task_managers/__init__.py,sha256=6VVe5ceSxXmQvBpjH-6aFud5dRJMNA6pu0qpAnfxpIA,460
16
+ mcp_use/task_managers/__init__.py,sha256=4dgW5N61iiPLpwjU2rrn_uqrL8mmDJFDaF9Lukzk65A,486
17
17
  mcp_use/task_managers/base.py,sha256=ksNdxTwq8N-zqymxVoKGnWXq9iqkLYC61uB91o6Mh-4,4888
18
- mcp_use/task_managers/http.py,sha256=XhrF73RGRnVctBVW2FlFrFTJR2pIGXhtNvfJFiW0Olw,1881
18
+ mcp_use/task_managers/sse.py,sha256=WysmjwqRI3meXMZY_F4y9tSBMvSiUZfTJQfitM5l6jQ,2529
19
19
  mcp_use/task_managers/stdio.py,sha256=DEISpXv4mo3d5a-WT8lkWbrXJwUh7QW0nMT_IM3fHGg,2269
20
- mcp_use/task_managers/websocket.py,sha256=SVgTLFogiynb48eyi6ZioWIKLLWiVBCNE59rXi6GrCM,1943
21
- mcp_use-1.0.0.dist-info/METADATA,sha256=SutQOwdz5oeqwsqGZJEgALeYG3evLZ8pNabca1lJppw,10113
22
- mcp_use-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
- mcp_use-1.0.0.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
24
- mcp_use-1.0.0.dist-info/RECORD,,
20
+ mcp_use/task_managers/websocket.py,sha256=ZbCqdGgzCRtsXzRGFws-f2OzH8cPAkN4sJNDwEpRmCc,1915
21
+ mcp_use-1.0.1.dist-info/METADATA,sha256=BZm7Zn7K33DKE2fLzRgDPl-oTpQRAuKW3ssxNkpEsxA,10203
22
+ mcp_use-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ mcp_use-1.0.1.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
24
+ mcp_use-1.0.1.dist-info/RECORD,,
@@ -1,62 +0,0 @@
1
- """
2
- HTTP connection management for MCP implementations.
3
-
4
- This module provides a connection manager for HTTP-based MCP connections.
5
- """
6
-
7
- import aiohttp
8
-
9
- from ..logging import logger
10
- from .base import ConnectionManager
11
-
12
-
13
- class HttpConnectionManager(ConnectionManager[aiohttp.ClientSession]):
14
- """Connection manager for HTTP-based MCP connections.
15
-
16
- This class handles the lifecycle of HTTP client sessions, ensuring proper
17
- connection establishment and cleanup.
18
- """
19
-
20
- def __init__(
21
- self,
22
- base_url: str,
23
- headers: dict[str, str] | None = None,
24
- ):
25
- """Initialize a new HTTP connection manager.
26
-
27
- Args:
28
- base_url: The base URL for HTTP requests
29
- headers: Optional headers to include in all HTTP requests
30
- """
31
- super().__init__()
32
- self.base_url = base_url.rstrip("/")
33
- self.headers = headers or {}
34
-
35
- async def _establish_connection(self) -> aiohttp.ClientSession:
36
- """Establish an HTTP client session.
37
-
38
- Returns:
39
- The established HTTP client session
40
-
41
- Raises:
42
- Exception: If session cannot be established
43
- """
44
- logger.debug(f"Creating HTTP client session for: {self.base_url}")
45
- try:
46
- session = aiohttp.ClientSession(headers=self.headers)
47
- return session
48
- except Exception as e:
49
- logger.error(f"Failed to create HTTP client session: {e}")
50
- raise
51
-
52
- async def _close_connection(self, connection: aiohttp.ClientSession) -> None:
53
- """Close the HTTP client session.
54
-
55
- Args:
56
- connection: The HTTP client session to close
57
- """
58
- try:
59
- logger.debug("Closing HTTP client session")
60
- await connection.close()
61
- except Exception as e:
62
- logger.warning(f"Error closing HTTP client session: {e}")