mcp-use 1.2.7__py3-none-any.whl → 1.2.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.

@@ -0,0 +1,303 @@
1
+ import asyncio
2
+ import time
3
+ from typing import ClassVar
4
+
5
+ import numpy as np
6
+ from fastembed import TextEmbedding
7
+ from langchain_core.tools import BaseTool
8
+ from pydantic import BaseModel, Field
9
+
10
+ from ...logging import logger
11
+ from .base_tool import MCPServerTool
12
+
13
+
14
+ class ToolSearchInput(BaseModel):
15
+ """Input for searching for tools across MCP servers"""
16
+
17
+ query: str = Field(description="The search query to find relevant tools")
18
+ top_k: int = Field(
19
+ default=100,
20
+ description="The maximum number of tools to return (defaults to 100)",
21
+ )
22
+
23
+
24
+ class SearchToolsTool(MCPServerTool):
25
+ """Tool for searching for tools across all MCP servers using semantic search."""
26
+
27
+ name: ClassVar[str] = "search_mcp_tools"
28
+ description: ClassVar[str] = (
29
+ "Search for relevant tools across all MCP servers using semantic search. "
30
+ "Provide a description of the tool you think you might need to be able to perform "
31
+ "the task you are assigned. Do not be too specific, the search will give you many "
32
+ "options. It is important you search for the tool, not for the goal. "
33
+ "If your first search doesn't yield relevant results, try using different keywords "
34
+ "or more general terms."
35
+ )
36
+ args_schema: ClassVar[type[BaseModel]] = ToolSearchInput
37
+
38
+ def __init__(self, server_manager):
39
+ """Initialize with server manager and create a search tool."""
40
+ super().__init__(server_manager)
41
+ self._search_tool = ToolSearchEngine(server_manager=server_manager)
42
+
43
+ async def _arun(self, query: str, top_k: int = 100) -> str:
44
+ """Search for tools across all MCP servers using semantic search."""
45
+ # Make sure the index is ready, and if not, allow the search_tools method to handle it
46
+ # No need to manually check or build the index here as the search_tools method will do that
47
+
48
+ # Perform search using our search tool instance
49
+ results = await self._search_tool.search_tools(
50
+ query, top_k=top_k, active_server=self.server_manager.active_server
51
+ )
52
+ return self.format_search_results(results)
53
+
54
+ def _run(self, query: str, top_k: int = 100) -> str:
55
+ """Synchronous version that raises a NotImplementedError - use _arun instead."""
56
+ raise NotImplementedError("SearchToolsTool requires async execution. Use _arun instead.")
57
+
58
+ def format_search_results(self, results: list[tuple[BaseTool, str, float]]) -> str:
59
+ """Format search results in a consistent format."""
60
+
61
+ # Only show top_k results
62
+ results = results
63
+
64
+ formatted_output = "Search results\n\n"
65
+
66
+ for i, (tool, server_name, score) in enumerate(results):
67
+ # Format score as percentage
68
+ if i < 5:
69
+ score_pct = f"{score * 100:.1f}%"
70
+ logger.info(f"{i}: {tool.name} ({score_pct} match)")
71
+ formatted_output += f"[{i + 1}] Tool: {tool.name} ({score_pct} match)\n"
72
+ formatted_output += f" Server: {server_name}\n"
73
+ formatted_output += f" Description: {tool.description}\n\n"
74
+
75
+ # Add footer with information about how to use the results
76
+ formatted_output += (
77
+ "\nTo use a tool, connect to the appropriate server first, then invoke the tool."
78
+ )
79
+
80
+ return formatted_output
81
+
82
+
83
+ class ToolSearchEngine:
84
+ """
85
+ Provides semantic search capabilities for MCP tools.
86
+ Uses vector similarity for semantic search with optional result caching.
87
+ """
88
+
89
+ def __init__(self, server_manager=None, use_caching: bool = True):
90
+ """
91
+ Initialize the tool search engine.
92
+
93
+ Args:
94
+ server_manager: The ServerManager instance to get tools from
95
+ use_caching: Whether to cache query results
96
+ """
97
+ self.server_manager = server_manager
98
+ self.use_caching = use_caching
99
+ self.is_indexed = False
100
+
101
+ # Initialize model components (loaded on demand)
102
+ self.model = None
103
+ self.embedding_function = None
104
+
105
+ # Data storage
106
+ self.tool_embeddings = {} # Maps tool name to embedding vector
107
+ self.tools_by_name = {} # Maps tool name to tool instance
108
+ self.server_by_tool = {} # Maps tool name to server name
109
+ self.tool_texts = {} # Maps tool name to searchable text
110
+ self.query_cache = {} # Caches search results by query
111
+
112
+ def _load_model(self) -> bool:
113
+ """Load the embedding model for semantic search if not already loaded."""
114
+ if self.model is not None:
115
+ return True
116
+
117
+ try:
118
+ self.model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
119
+ self.embedding_function = lambda texts: list(self.model.embed(texts))
120
+ return True
121
+ except Exception:
122
+ return False
123
+
124
+ async def start_indexing(self) -> None:
125
+ """Index the tools from the server manager."""
126
+ if not self.server_manager:
127
+ return
128
+
129
+ # Get tools from server manager
130
+ server_tools = self.server_manager._server_tools
131
+
132
+ if not server_tools:
133
+ # Try to prefetch tools first
134
+ if hasattr(self.server_manager, "_prefetch_server_tools"):
135
+ await self.server_manager._prefetch_server_tools()
136
+ server_tools = self.server_manager._server_tools
137
+
138
+ if server_tools:
139
+ await self.index_tools(server_tools)
140
+
141
+ async def index_tools(self, server_tools: dict[str, list[BaseTool]]) -> None:
142
+ """
143
+ Index all tools from all servers for search.
144
+
145
+ Args:
146
+ server_tools: dictionary mapping server names to their tools
147
+ """
148
+ # Clear previous indexes
149
+ self.tool_embeddings = {}
150
+ self.tools_by_name = {}
151
+ self.server_by_tool = {}
152
+ self.tool_texts = {}
153
+ self.query_cache = {}
154
+ self.is_indexed = False
155
+
156
+ # Collect all tools and their descriptions
157
+ for server_name, tools in server_tools.items():
158
+ for tool in tools:
159
+ # Create text representation for search
160
+ tool_text = f"{tool.name}: {tool.description}"
161
+
162
+ # Store tool information
163
+ self.tools_by_name[tool.name] = tool
164
+ self.server_by_tool[tool.name] = server_name
165
+ self.tool_texts[tool.name] = tool_text.lower() # For case-insensitive search
166
+
167
+ if not self.tool_texts:
168
+ return
169
+
170
+ # Generate embeddings
171
+ if self._load_model():
172
+ tool_names = list(self.tool_texts.keys())
173
+ tool_texts = [self.tool_texts[name] for name in tool_names]
174
+
175
+ try:
176
+ embeddings = self.embedding_function(tool_texts)
177
+ for name, embedding in zip(tool_names, embeddings, strict=True):
178
+ self.tool_embeddings[name] = embedding
179
+
180
+ # Mark as indexed if we successfully embedded tools
181
+ self.is_indexed = len(self.tool_embeddings) > 0
182
+ except Exception:
183
+ return
184
+
185
+ def search(self, query: str, top_k: int = 5) -> list[tuple[BaseTool, str, float]]:
186
+ """
187
+ Search for tools that match the query using semantic search.
188
+
189
+ Args:
190
+ query: The search query
191
+ top_k: Number of top results to return
192
+
193
+ Returns:
194
+ list of tuples containing (tool, server_name, score)
195
+ """
196
+ if not self.is_indexed:
197
+ return []
198
+
199
+ # Check cache first
200
+ cache_key = f"semantic:{query}:{top_k}"
201
+ if self.use_caching and cache_key in self.query_cache:
202
+ return self.query_cache[cache_key]
203
+
204
+ # Ensure model and embeddings exist
205
+ if not self._load_model() or not self.tool_embeddings:
206
+ return []
207
+
208
+ # Generate embedding for the query
209
+ try:
210
+ query_embedding = self.embedding_function([query])[0]
211
+ except Exception:
212
+ return []
213
+
214
+ # Calculate similarity scores
215
+ scores = {}
216
+ for tool_name, embedding in self.tool_embeddings.items():
217
+ # Calculate cosine similarity
218
+ similarity = np.dot(query_embedding, embedding) / (
219
+ np.linalg.norm(query_embedding) * np.linalg.norm(embedding)
220
+ )
221
+ scores[tool_name] = float(similarity)
222
+
223
+ # Sort by score and get top_k results
224
+ sorted_results = sorted(scores.items(), key=lambda x: x[1], reverse=True)[:top_k]
225
+
226
+ # Format results
227
+ results = []
228
+ for tool_name, score in sorted_results:
229
+ tool = self.tools_by_name.get(tool_name)
230
+ server_name = self.server_by_tool.get(tool_name)
231
+ if tool and server_name:
232
+ results.append((tool, server_name, score))
233
+
234
+ # Cache results
235
+ if self.use_caching:
236
+ self.query_cache[cache_key] = results
237
+
238
+ return results
239
+
240
+ async def search_tools(self, query: str, top_k: int = 100, active_server: str = None) -> str:
241
+ """
242
+ Search for tools across all MCP servers using semantic search.
243
+
244
+ Args:
245
+ query: The search query to find relevant tools
246
+ top_k: Number of top results to return
247
+ active_server: Name of the currently active server (for highlighting)
248
+
249
+ Returns:
250
+ String with formatted search results
251
+ """
252
+ # Ensure the index is built or build it
253
+ if not self.is_indexed:
254
+ # Try to build the index
255
+ if self.server_manager and self.server_manager._server_tools:
256
+ await self.index_tools(self.server_manager._server_tools)
257
+ else:
258
+ # If we don't have server_manager or tools, try to index directly
259
+ await self.start_indexing()
260
+
261
+ # Wait for indexing to complete (maximum 10 seconds)
262
+ start_time = time.time()
263
+ timeout = 10 # seconds
264
+ while not self.is_indexed and (time.time() - start_time) < timeout:
265
+ await asyncio.sleep(0.5)
266
+
267
+ # If still not indexed, return a friendly message
268
+ if not self.is_indexed:
269
+ return (
270
+ "I'm still preparing the tool index. Please try your search again in a moment. "
271
+ "This usually takes just a few seconds to complete."
272
+ )
273
+
274
+ # If the server manager has an active server but it wasn't provided, use it
275
+ if (
276
+ active_server is None
277
+ and self.server_manager
278
+ and hasattr(self.server_manager, "active_server")
279
+ ):
280
+ active_server = self.server_manager.active_server
281
+
282
+ results = self.search(query, top_k=top_k)
283
+ if not results:
284
+ return (
285
+ "No relevant tools found. The search provided no results. "
286
+ "You can try searching again with different keywords. "
287
+ "Try using more general terms or focusing on the capability you need."
288
+ )
289
+
290
+ # If there's an active server, mark it in the results
291
+ if active_server:
292
+ # Create a new results list with marked active server
293
+ marked_results = []
294
+ for tool, server_name, score in results:
295
+ # If this is the active server, add "(ACTIVE)" marker
296
+ display_server = (
297
+ f"{server_name} (ACTIVE)" if server_name == active_server else server_name
298
+ )
299
+ marked_results.append((tool, display_server, score))
300
+ results = marked_results
301
+
302
+ # Format and return the results
303
+ return results
@@ -0,0 +1,167 @@
1
+ import json
2
+ from typing import Any, ClassVar
3
+
4
+ from langchain_core.tools import BaseTool
5
+ from pydantic import BaseModel, Field
6
+
7
+ from mcp_use.logging import logger
8
+
9
+ from .base_tool import MCPServerTool
10
+
11
+
12
+ class UseToolInput(BaseModel):
13
+ """Input for using a tool from a specific server"""
14
+
15
+ server_name: str = Field(description="The name of the MCP server containing the tool")
16
+ tool_name: str = Field(description="The name of the tool to execute")
17
+ tool_input: dict[str, Any] | str = Field(
18
+ description="The input to pass to the tool. Can be a dictionary of parameters or a string"
19
+ )
20
+
21
+
22
+ class UseToolFromServerTool(MCPServerTool):
23
+ """Tool for directly executing a tool from a specific server."""
24
+
25
+ name: ClassVar[str] = "use_tool_from_server"
26
+ description: ClassVar[str] = (
27
+ "Execute a specific tool on a specific server without first connecting to it. "
28
+ "This is a direct execution shortcut that combines connection and tool execution "
29
+ "into a single step. Specify the server name, tool name, and the input to the tool."
30
+ )
31
+ args_schema: ClassVar[type[BaseModel]] = UseToolInput
32
+
33
+ async def _arun(
34
+ self, server_name: str, tool_name: str, tool_input: dict[str, Any] | str
35
+ ) -> str:
36
+ """Execute a tool from a specific server."""
37
+ # Check if server exists
38
+ servers = self.server_manager.client.get_server_names()
39
+ if server_name not in servers:
40
+ available = ", ".join(servers) if servers else "none"
41
+ return f"Server '{server_name}' not found. Available servers: {available}"
42
+
43
+ # Connect to the server if not already connected or not the active server
44
+ is_connected = server_name == self.server_manager.active_server
45
+
46
+ if not is_connected:
47
+ try:
48
+ # Create or get session for this server
49
+ try:
50
+ session = self.server_manager.client.get_session(server_name)
51
+ logger.debug(f"Using existing session for server '{server_name}'")
52
+ except ValueError:
53
+ logger.debug(f"Creating new session for server '{server_name}' for tool use")
54
+ session = await self.server_manager.client.create_session(server_name)
55
+
56
+ # Check if we have tools for this server, if not get them
57
+ if server_name not in self.server_manager._server_tools:
58
+ connector = session.connector
59
+ self.server_manager._server_tools[
60
+ server_name
61
+ ] = await self.server_manager.adapter._create_tools_from_connectors([connector])
62
+ self.server_manager.initialized_servers[server_name] = True
63
+ except Exception as e:
64
+ logger.error(f"Error connecting to server '{server_name}' for tool use: {e}")
65
+ return f"Failed to connect to server '{server_name}': {str(e)}"
66
+
67
+ # Get tools for the server
68
+ server_tools = self.server_manager._server_tools.get(server_name, [])
69
+ if not server_tools:
70
+ return f"No tools found for server '{server_name}'"
71
+
72
+ # Find the requested tool
73
+ target_tool = None
74
+ for tool in server_tools:
75
+ if tool.name == tool_name:
76
+ target_tool = tool
77
+ break
78
+
79
+ if not target_tool:
80
+ tool_names = [t.name for t in server_tools]
81
+ return (
82
+ f"Tool '{tool_name}' not found on server '{server_name}'. "
83
+ f"Available tools: {', '.join(tool_names)}"
84
+ )
85
+
86
+ # Execute the tool with the provided input
87
+ try:
88
+ # Parse the input based on target tool's schema
89
+ structured_input = self._parse_tool_input(target_tool, tool_input)
90
+ if structured_input is None:
91
+ return (
92
+ f"Could not parse input for tool '{tool_name}'."
93
+ " Please check the input format and try again."
94
+ )
95
+
96
+ # Store the previous active server
97
+ previous_active = self.server_manager.active_server
98
+
99
+ # Temporarily set this server as active
100
+ self.server_manager.active_server = server_name
101
+
102
+ # Execute the tool
103
+ logger.info(
104
+ f"Executing tool '{tool_name}' on server '{server_name}'"
105
+ "with input: {structured_input}"
106
+ )
107
+ result = await target_tool._arun(**structured_input)
108
+
109
+ # Restore the previous active server
110
+ self.server_manager.active_server = previous_active
111
+
112
+ return result
113
+
114
+ except Exception as e:
115
+ logger.error(f"Error executing tool '{tool_name}' on server '{server_name}': {e}")
116
+ return (
117
+ f"Error executing tool '{tool_name}' on server '{server_name}': {str(e)}. "
118
+ f"Make sure the input format is correct for this tool."
119
+ )
120
+
121
+ def _parse_tool_input(self, tool: BaseTool, input_data: dict[str, Any] | str) -> dict[str, Any]:
122
+ """
123
+ Parse the input data according to the tool's schema.
124
+
125
+ Args:
126
+ tool: The target tool
127
+ input_data: The input data, either a dictionary or a string
128
+
129
+ Returns:
130
+ A dictionary with properly structured input for the tool
131
+ """
132
+ # If input is already a dict, use it directly
133
+ if isinstance(input_data, dict):
134
+ return input_data
135
+
136
+ # Try to parse as JSON first
137
+ if isinstance(input_data, str):
138
+ try:
139
+ return json.loads(input_data)
140
+ except json.JSONDecodeError:
141
+ pass
142
+
143
+ # For string input, we need to determine which parameter name to use
144
+ if hasattr(tool, "args_schema") and tool.args_schema:
145
+ schema_cls = tool.args_schema
146
+ field_names = list(schema_cls.__fields__.keys())
147
+
148
+ # If schema has only one field, use that
149
+ if len(field_names) == 1:
150
+ return {field_names[0]: input_data}
151
+
152
+ # Look for common input field names
153
+ for name in field_names:
154
+ if name.lower() in ["input", "query", "url", tool.name.lower()]:
155
+ return {name: input_data}
156
+
157
+ # Default to first field if we can't determine
158
+ return {field_names[0]: input_data}
159
+
160
+ # If we get here something went wrong
161
+ return None
162
+
163
+ def _run(self, server_name: str, tool_name: str, tool_input: dict[str, Any] | str) -> str:
164
+ """Synchronous version that raises a NotImplementedError."""
165
+ raise NotImplementedError(
166
+ "UseToolFromServerTool requires async execution. Use _arun instead."
167
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-use
3
- Version: 1.2.7
3
+ Version: 1.2.9
4
4
  Summary: MCP Library for LLMs
5
5
  Author-email: Pietro Zullo <pietro.zullo@gmail.com>
6
6
  License: MIT
@@ -35,6 +35,8 @@ Requires-Dist: pytest>=7.4.0; extra == 'dev'
35
35
  Requires-Dist: ruff>=0.1.0; extra == 'dev'
36
36
  Provides-Extra: openai
37
37
  Requires-Dist: openai>=1.10.0; extra == 'openai'
38
+ Provides-Extra: search
39
+ Requires-Dist: fastembed>=0.0.1; extra == 'search'
38
40
  Description-Content-Type: text/markdown
39
41
 
40
42
  <picture>
@@ -48,6 +50,7 @@ Description-Content-Type: text/markdown
48
50
  [![PyPI Version](https://img.shields.io/pypi/v/mcp_use.svg)](https://pypi.org/project/mcp_use/)
49
51
  [![Python Versions](https://img.shields.io/pypi/pyversions/mcp_use.svg)](https://pypi.org/project/mcp_use/)
50
52
  [![Documentation](https://img.shields.io/badge/docs-mcp--use.io-blue)](https://docs.mcp-use.io)
53
+ [![Website](https://img.shields.io/badge/website-mcp--use.io-blue)](https://mcp-use.io)
51
54
  [![License](https://img.shields.io/github/license/pietrozullo/mcp-use)](https://github.com/pietrozullo/mcp-use/blob/main/LICENSE)
52
55
  [![Code style: Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
53
56
  [![GitHub stars](https://img.shields.io/github/stars/pietrozullo/mcp-use?style=social)](https://github.com/pietrozullo/mcp-use/stargazers)
@@ -63,13 +66,14 @@ Description-Content-Type: text/markdown
63
66
 
64
67
  | Feature | Description |
65
68
  |---------|-------------|
66
- | 🔄 **Ease of use** | Create your first MCP capable agent you need only 6 lines of code |
67
- | 🤖 **LLM Flexibility** | Works with any langchain supported LLM that supports tool calling (OpenAI, Anthropic, Groq, LLama etc.) |
68
- | 🌐 **HTTP Support** | Direct connection to MCP servers running on specific HTTP ports |
69
- | ⚙️ **Dynamic Server Selection** | Agents can dynamically choose the most appropriate MCP server for a given task from the available pool |
70
- | 🧩 **Multi-Server Support** | Use multiple MCP servers simultaneously in a single agent |
71
- | 🛡️ **Tool Restrictions** | Restrict potentially dangerous tools like file system or network access |
72
- | 🔧 **Custom Agents** | Build your own agents with any framework using the LangChain adapter or create new adapters |
69
+ | 🔄 [**Ease of use**](#quick-start) | Create your first MCP capable agent you need only 6 lines of code |
70
+ | 🤖 [**LLM Flexibility**](#installing-langchain-providers) | Works with any langchain supported LLM that supports tool calling (OpenAI, Anthropic, Groq, LLama etc.) |
71
+ | 🌐 [**Code Builder**](https://mcp-use.io/builder) | Explore MCP capabilities and generate starter code with the interactive [code builder](https://mcp-use.io/builder). |
72
+ | 🔗 [**HTTP Support**](#http-connection-example) | Direct connection to MCP servers running on specific HTTP ports |
73
+ | ⚙️ [**Dynamic Server Selection**](#dynamic-server-selection-server-manager) | Agents can dynamically choose the most appropriate MCP server for a given task from the available pool |
74
+ | 🧩 [**Multi-Server Support**](#multi-server-support) | Use multiple MCP servers simultaneously in a single agent |
75
+ | 🛡️ [**Tool Restrictions**](#tool-access-control) | Restrict potentially dangerous tools like file system or network access |
76
+ | 🔧 [**Custom Agents**](#build-a-custom-agent) | Build your own agents with any framework using the LangChain adapter or create new adapters |
73
77
 
74
78
 
75
79
  # Quick start
@@ -182,6 +186,43 @@ Example configuration file (`browser_mcp.json`):
182
186
 
183
187
  For other settings, models, and more, check out the documentation.
184
188
 
189
+ ## Streaming Agent Output
190
+
191
+ MCP-Use supports asynchronous streaming of agent output using the `astream` method on `MCPAgent`. This allows you to receive incremental results, tool actions, and intermediate steps as they are generated by the agent, enabling real-time feedback and progress reporting.
192
+
193
+ ### How to use
194
+
195
+ Call `agent.astream(query)` and iterate over the results asynchronously:
196
+
197
+ ```python
198
+ async for chunk in agent.astream("Find the best restaurant in San Francisco"):
199
+ print(chunk["messages"], end="", flush=True)
200
+ ```
201
+
202
+ Each chunk is a dictionary containing keys such as `actions`, `steps`, `messages`, and (on the last chunk) `output`. This enables you to build responsive UIs or log agent progress in real time.
203
+
204
+ #### Example: Streaming in Practice
205
+
206
+ ```python
207
+ import asyncio
208
+ import os
209
+ from dotenv import load_dotenv
210
+ from langchain_openai import ChatOpenAI
211
+ from mcp_use import MCPAgent, MCPClient
212
+
213
+ async def main():
214
+ load_dotenv()
215
+ client = MCPClient.from_config_file("browser_mcp.json")
216
+ llm = ChatOpenAI(model="gpt-4o")
217
+ agent = MCPAgent(llm=llm, client=client, max_steps=30)
218
+ async for chunk in agent.astream("Look for job at nvidia for machine learning engineer."):
219
+ print(chunk["messages"], end="", flush=True)
220
+
221
+ if __name__ == "__main__":
222
+ asyncio.run(main())
223
+ ```
224
+
225
+ This streaming interface is ideal for applications that require real-time updates, such as chatbots, dashboards, or interactive notebooks.
185
226
 
186
227
  # Example Use Cases
187
228
 
@@ -342,7 +383,7 @@ if __name__ == "__main__":
342
383
 
343
384
  ## HTTP Connection Example
344
385
 
345
- MCP-Use now supports HTTP connections, allowing you to connect to MCP servers running on specific HTTP ports. This feature is particularly useful for integrating with web-based MCP servers.
386
+ MCP-Use supports HTTP connections, allowing you to connect to MCP servers running on specific HTTP ports. This feature is particularly useful for integrating with web-based MCP servers.
346
387
 
347
388
  Here's an example of how to use the HTTP connection feature:
348
389
 
@@ -610,7 +651,7 @@ This is useful when you only need to see the agent's steps and decision-making p
610
651
 
611
652
  # Contributing
612
653
 
613
- We love contributions! Feel free to open issues for bugs or feature requests.
654
+ We love contributions! Feel free to open issues for bugs or feature requests. Look at [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
614
655
 
615
656
  # Requirements
616
657
 
@@ -5,24 +5,33 @@ mcp_use/logging.py,sha256=UhQdMx0H0q08-ZPjY_hAJVErkEUAkU1oahHqwdfdK_U,4274
5
5
  mcp_use/session.py,sha256=Z4EZTUnQUX0QyGMzkJIrMRTX4SDk6qQUoBld408LIJE,3449
6
6
  mcp_use/adapters/__init__.py,sha256=-xCrgPThuX7x0PHGFDdjb7M-mgw6QV3sKu5PM7ShnRg,275
7
7
  mcp_use/adapters/base.py,sha256=ixLHXp8FWdyZPx7Kh6s-4jEVs3qT4DWrApSLXfqzNws,6141
8
- mcp_use/adapters/langchain_adapter.py,sha256=mbOkWHMgHJJNJYFXYLCk3JjIT0CRW_iiu5eZtxsWEmk,6309
9
- mcp_use/agents/__init__.py,sha256=7QCfjE9WA50r-W8CS7IzUZMuhLgm8xSuKH1kYWdFU64,324
8
+ mcp_use/adapters/langchain_adapter.py,sha256=s8IHPPtqqXMmWQfeBqwESs3SZA6_ECSiGRwdTOIWki0,6417
9
+ mcp_use/agents/__init__.py,sha256=N3eVYP2PxqNO2KcQv5fY8UMUX2W3eLTNkkzuFIJ1DUA,261
10
10
  mcp_use/agents/base.py,sha256=bfuldi_89AbSbNc8KeTiCArRT9V62CNxHOWYkLHWjyA,1605
11
- mcp_use/agents/mcpagent.py,sha256=kSNqmF728LrEYfzfvW8h8llqC877vJLcn-DJodYVucU,23988
12
- mcp_use/agents/server_manager.py,sha256=ShmjrvDtmU7dJtfVlw_srC3t5f_B-QtifzIiV4mfsRA,11315
11
+ mcp_use/agents/mcpagent.py,sha256=1U2HHOk-P-W4O81wdmEXaVWcGU2VQ9xyGaWykK1VCVQ,26954
13
12
  mcp_use/agents/prompts/system_prompt_builder.py,sha256=GH5Pvl49IBpKpZA9YTI83xMsdYSkRN_hw4LFHkKtxbg,4122
14
13
  mcp_use/agents/prompts/templates.py,sha256=AZKrGWuI516C-PmyOPvxDBibNdqJtN24sOHTGR06bi4,1933
15
14
  mcp_use/connectors/__init__.py,sha256=jnd-7pPPJMb0UNJ6aD9lInj5Tlamc8lA_mFyG8RWJpo,385
16
- mcp_use/connectors/base.py,sha256=5TcXB-I5zrwPtedB6dShceNucsK3wHBeGC2yDVq8X48,4885
15
+ mcp_use/connectors/base.py,sha256=5V8XHh3K-_zMBG22c6cxHynLyZps7M8FTIMt29OJa8o,5599
17
16
  mcp_use/connectors/http.py,sha256=2ZG5JxcK1WZ4jkTfTir6bEQLMxXBTPHyi0s42RHGeFs,2837
18
17
  mcp_use/connectors/stdio.py,sha256=MTzsqmVVihACUKngE-g5BignK3jAFds2CFv3aSzbJfs,2608
19
18
  mcp_use/connectors/websocket.py,sha256=LeU53YI3zjbwKq5GzFRziqA_z9Dn5qACiNyxWDrn2ns,9540
19
+ mcp_use/managers/__init__.py,sha256=rzsJbOhtlmxNQLGcdmtmHaiExEXmiQiUuzPrAgKhAJw,439
20
+ mcp_use/managers/server_manager.py,sha256=YVl5ciNIQfVzP-BR9hA0ac6YSwq0WChpA_Lxvh2e9HE,3984
21
+ mcp_use/managers/tools/__init__.py,sha256=JrA5iTRdtbgwROJE8pQ7GH1sYnqBRcgj4NzFVADKbQ4,510
22
+ mcp_use/managers/tools/base_tool.py,sha256=Jbbp7SwmHKDk8jT_6yVIv7iNsn6KaV_PljWuhhLcbXg,509
23
+ mcp_use/managers/tools/connect_server.py,sha256=MGYQCl11q-w6gSIYuT44dDk7ILV3Oh7kGAJ4fsNXbso,2923
24
+ mcp_use/managers/tools/disconnect_server.py,sha256=4487QlLbXAh9JyfGioc6DMWd0n_dkaa8RLMvsoNZv3E,1602
25
+ mcp_use/managers/tools/get_active_server.py,sha256=LRcHbKZopMl1PiO4D4JS4s0fwtrvtMtvb4kpnoAE8fQ,1015
26
+ mcp_use/managers/tools/list_servers_tool.py,sha256=OPDSMNe-VuAhlUyhDnR4CiuZFpoMhnhWpAablwO5S0k,1897
27
+ mcp_use/managers/tools/search_tools.py,sha256=0BfFesCBJsdCAG2tPCM-c49tmBJLwLQoR_U-sj-rp2s,11628
28
+ mcp_use/managers/tools/use_tool.py,sha256=r7k7uMYzrk353qw7M5h1utu_IR2G85uMZkrNcg2RyZA,6824
20
29
  mcp_use/task_managers/__init__.py,sha256=4dgW5N61iiPLpwjU2rrn_uqrL8mmDJFDaF9Lukzk65A,486
21
30
  mcp_use/task_managers/base.py,sha256=ksNdxTwq8N-zqymxVoKGnWXq9iqkLYC61uB91o6Mh-4,4888
22
31
  mcp_use/task_managers/sse.py,sha256=WysmjwqRI3meXMZY_F4y9tSBMvSiUZfTJQfitM5l6jQ,2529
23
32
  mcp_use/task_managers/stdio.py,sha256=DEISpXv4mo3d5a-WT8lkWbrXJwUh7QW0nMT_IM3fHGg,2269
24
33
  mcp_use/task_managers/websocket.py,sha256=ZbCqdGgzCRtsXzRGFws-f2OzH8cPAkN4sJNDwEpRmCc,1915
25
- mcp_use-1.2.7.dist-info/METADATA,sha256=GsNTID4AHT6Th_2Z1Us2tlcE9dKu4F9BxNTtFZK05jk,18163
26
- mcp_use-1.2.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
- mcp_use-1.2.7.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
28
- mcp_use-1.2.7.dist-info/RECORD,,
34
+ mcp_use-1.2.9.dist-info/METADATA,sha256=s84Li3g9TI5YdlKS25fd3m7hEEDydMIFkXbdn1axMmA,20198
35
+ mcp_use-1.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
36
+ mcp_use-1.2.9.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
37
+ mcp_use-1.2.9.dist-info/RECORD,,