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.
- mcp_use/adapters/langchain_adapter.py +3 -0
- mcp_use/agents/__init__.py +0 -2
- mcp_use/agents/mcpagent.py +85 -7
- mcp_use/connectors/base.py +20 -0
- mcp_use/managers/__init__.py +21 -0
- mcp_use/managers/server_manager.py +101 -0
- mcp_use/managers/tools/__init__.py +17 -0
- mcp_use/managers/tools/base_tool.py +19 -0
- mcp_use/managers/tools/connect_server.py +69 -0
- mcp_use/managers/tools/disconnect_server.py +45 -0
- mcp_use/managers/tools/get_active_server.py +32 -0
- mcp_use/managers/tools/list_servers_tool.py +52 -0
- mcp_use/managers/tools/search_tools.py +303 -0
- mcp_use/managers/tools/use_tool.py +167 -0
- {mcp_use-1.2.7.dist-info → mcp_use-1.2.9.dist-info}/METADATA +51 -10
- {mcp_use-1.2.7.dist-info → mcp_use-1.2.9.dist-info}/RECORD +18 -9
- mcp_use/agents/server_manager.py +0 -282
- {mcp_use-1.2.7.dist-info → mcp_use-1.2.9.dist-info}/WHEEL +0 -0
- {mcp_use-1.2.7.dist-info → mcp_use-1.2.9.dist-info}/licenses/LICENSE +0 -0
mcp_use/agents/server_manager.py
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
from langchain_core.tools import BaseTool, StructuredTool
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
3
|
-
|
|
4
|
-
from mcp_use.client import MCPClient
|
|
5
|
-
from mcp_use.logging import logger
|
|
6
|
-
|
|
7
|
-
from ..adapters.langchain_adapter import LangChainAdapter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ServerActionInput(BaseModel):
|
|
11
|
-
"""Base input for server-related actions"""
|
|
12
|
-
|
|
13
|
-
server_name: str = Field(description="The name of the MCP server")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class DisconnectServerInput(BaseModel):
|
|
17
|
-
"""Empty input for disconnecting from the current server"""
|
|
18
|
-
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class ListServersInput(BaseModel):
|
|
23
|
-
"""Empty input for listing available servers"""
|
|
24
|
-
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class CurrentServerInput(BaseModel):
|
|
29
|
-
"""Empty input for checking current server"""
|
|
30
|
-
|
|
31
|
-
pass
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ServerManager:
|
|
35
|
-
"""Manages MCP servers and provides tools for server selection and management.
|
|
36
|
-
|
|
37
|
-
This class allows an agent to discover and select which MCP server to use,
|
|
38
|
-
dynamically activating the tools for the selected server.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
def __init__(self, client: MCPClient, adapter: LangChainAdapter) -> None:
|
|
42
|
-
"""Initialize the server manager.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
client: The MCPClient instance managing server connections
|
|
46
|
-
adapter: The LangChainAdapter for converting MCP tools to LangChain tools
|
|
47
|
-
"""
|
|
48
|
-
self.client = client
|
|
49
|
-
self.adapter = adapter
|
|
50
|
-
self.active_server: str | None = None
|
|
51
|
-
self.initialized_servers: dict[str, bool] = {}
|
|
52
|
-
self._server_tools: dict[str, list[BaseTool]] = {}
|
|
53
|
-
|
|
54
|
-
async def initialize(self) -> None:
|
|
55
|
-
"""Initialize the server manager and prepare server management tools."""
|
|
56
|
-
# Make sure we have server configurations
|
|
57
|
-
if not self.client.get_server_names():
|
|
58
|
-
logger.warning("No MCP servers defined in client configuration")
|
|
59
|
-
|
|
60
|
-
async def get_server_management_tools(self) -> list[BaseTool]:
|
|
61
|
-
"""Get tools for managing server connections.
|
|
62
|
-
|
|
63
|
-
Returns:
|
|
64
|
-
List of LangChain tools for server management
|
|
65
|
-
"""
|
|
66
|
-
# Create structured tools for server management with direct parameter passing
|
|
67
|
-
list_servers_tool = StructuredTool.from_function(
|
|
68
|
-
coroutine=self.list_servers,
|
|
69
|
-
name="list_mcp_servers",
|
|
70
|
-
description="Lists all available MCP (Model Context Protocol) servers that can be "
|
|
71
|
-
"connected to, along with the tools available on each server. "
|
|
72
|
-
"Use this tool to discover servers and see what functionalities they offer.",
|
|
73
|
-
args_schema=ListServersInput,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
connect_server_tool = StructuredTool.from_function(
|
|
77
|
-
coroutine=self.connect_to_server,
|
|
78
|
-
name="connect_to_mcp_server",
|
|
79
|
-
description="Connect to a specific MCP (Model Context Protocol) server to use its "
|
|
80
|
-
"tools. Use this tool to connect to a specific server and use its tools.",
|
|
81
|
-
args_schema=ServerActionInput,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
get_active_server_tool = StructuredTool.from_function(
|
|
85
|
-
coroutine=self.get_active_server,
|
|
86
|
-
name="get_active_mcp_server",
|
|
87
|
-
description="Get the currently active MCP (Model Context Protocol) server",
|
|
88
|
-
args_schema=CurrentServerInput,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
disconnect_server_tool = StructuredTool.from_function(
|
|
92
|
-
func=None,
|
|
93
|
-
coroutine=self.disconnect_from_server,
|
|
94
|
-
name="disconnect_from_mcp_server",
|
|
95
|
-
description="Disconnect from the currently active MCP (Model Context Protocol) server",
|
|
96
|
-
args_schema=DisconnectServerInput,
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
return [
|
|
100
|
-
list_servers_tool,
|
|
101
|
-
connect_server_tool,
|
|
102
|
-
get_active_server_tool,
|
|
103
|
-
disconnect_server_tool,
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
async def list_servers(self) -> str:
|
|
107
|
-
"""List all available MCP servers along with their available tools.
|
|
108
|
-
|
|
109
|
-
Returns:
|
|
110
|
-
String listing all available servers and their tools.
|
|
111
|
-
"""
|
|
112
|
-
servers = self.client.get_server_names()
|
|
113
|
-
if not servers:
|
|
114
|
-
return "No MCP servers are currently defined."
|
|
115
|
-
|
|
116
|
-
result = "Available MCP servers:\n"
|
|
117
|
-
for i, server_name in enumerate(servers):
|
|
118
|
-
active_marker = " (ACTIVE)" if server_name == self.active_server else ""
|
|
119
|
-
result += f"{i + 1}. {server_name}{active_marker}\n"
|
|
120
|
-
|
|
121
|
-
tools: list[BaseTool] = []
|
|
122
|
-
try:
|
|
123
|
-
# Check cache first
|
|
124
|
-
if server_name in self._server_tools:
|
|
125
|
-
tools = self._server_tools[server_name]
|
|
126
|
-
else:
|
|
127
|
-
# Attempt to get/create session without setting active
|
|
128
|
-
session = None
|
|
129
|
-
try:
|
|
130
|
-
session = self.client.get_session(server_name)
|
|
131
|
-
logger.debug(
|
|
132
|
-
f"Using existing session for server '{server_name}' to list tools."
|
|
133
|
-
)
|
|
134
|
-
except ValueError:
|
|
135
|
-
try:
|
|
136
|
-
# Only create session if needed, don't set active
|
|
137
|
-
session = await self.client.create_session(server_name)
|
|
138
|
-
logger.debug(f"Temporarily created session for server '{server_name}'")
|
|
139
|
-
except Exception:
|
|
140
|
-
logger.warning(f"Could not create session for server '{server_name}'")
|
|
141
|
-
|
|
142
|
-
# Fetch tools if session is available
|
|
143
|
-
if session:
|
|
144
|
-
try:
|
|
145
|
-
connector = session.connector
|
|
146
|
-
fetched_tools = await self.adapter._create_tools_from_connectors(
|
|
147
|
-
[connector]
|
|
148
|
-
)
|
|
149
|
-
self._server_tools[server_name] = fetched_tools # Cache tools
|
|
150
|
-
self.initialized_servers[server_name] = True # Mark as initialized
|
|
151
|
-
tools = fetched_tools
|
|
152
|
-
logger.debug(f"Fetched {len(tools)} tools for server '{server_name}'.")
|
|
153
|
-
except Exception as e:
|
|
154
|
-
logger.warning(f"Could not fetch tools for server '{server_name}': {e}")
|
|
155
|
-
# Keep tools as empty list if fetching failed
|
|
156
|
-
|
|
157
|
-
# Append tool names to the result string
|
|
158
|
-
if tools:
|
|
159
|
-
tool_names = ", ".join([tool.name for tool in tools])
|
|
160
|
-
result += f" Tools: {tool_names}\n"
|
|
161
|
-
else:
|
|
162
|
-
result += " Tools: (Could not retrieve or none available)\n"
|
|
163
|
-
|
|
164
|
-
except Exception as e:
|
|
165
|
-
logger.error(f"Unexpected error listing tools for server '{server_name}': {e}")
|
|
166
|
-
result += " Tools: (Error retrieving tools)\n"
|
|
167
|
-
|
|
168
|
-
return result
|
|
169
|
-
|
|
170
|
-
async def connect_to_server(self, server_name: str) -> str:
|
|
171
|
-
"""Connect to a specific MCP server.
|
|
172
|
-
|
|
173
|
-
Args:
|
|
174
|
-
server_name: The name of the server to connect to
|
|
175
|
-
|
|
176
|
-
Returns:
|
|
177
|
-
Status message about the connection
|
|
178
|
-
"""
|
|
179
|
-
# Check if server exists
|
|
180
|
-
servers = self.client.get_server_names()
|
|
181
|
-
if server_name not in servers:
|
|
182
|
-
available = ", ".join(servers) if servers else "none"
|
|
183
|
-
return f"Server '{server_name}' not found. Available servers: {available}"
|
|
184
|
-
|
|
185
|
-
# If we're already connected to this server, just return
|
|
186
|
-
if self.active_server == server_name:
|
|
187
|
-
return f"Already connected to MCP server '{server_name}'"
|
|
188
|
-
|
|
189
|
-
try:
|
|
190
|
-
# Create or get session for this server
|
|
191
|
-
try:
|
|
192
|
-
session = self.client.get_session(server_name)
|
|
193
|
-
logger.debug(f"Using existing session for server '{server_name}'")
|
|
194
|
-
except ValueError:
|
|
195
|
-
logger.debug(f"Creating new session for server '{server_name}'")
|
|
196
|
-
session = await self.client.create_session(server_name)
|
|
197
|
-
|
|
198
|
-
# Set as active server
|
|
199
|
-
self.active_server = server_name
|
|
200
|
-
|
|
201
|
-
# Initialize server tools if not already initialized
|
|
202
|
-
if server_name not in self._server_tools:
|
|
203
|
-
connector = session.connector
|
|
204
|
-
self._server_tools[server_name] = await self.adapter._create_tools_from_connectors(
|
|
205
|
-
[connector]
|
|
206
|
-
)
|
|
207
|
-
self.initialized_servers[server_name] = True
|
|
208
|
-
|
|
209
|
-
server_tools = self._server_tools.get(server_name, [])
|
|
210
|
-
num_tools = len(server_tools)
|
|
211
|
-
|
|
212
|
-
tool_descriptions = "\nAvailable tools for this server:\n"
|
|
213
|
-
for i, tool in enumerate(server_tools):
|
|
214
|
-
tool_descriptions += f"{i + 1}. {tool.name}: {tool.description}\n"
|
|
215
|
-
|
|
216
|
-
return (
|
|
217
|
-
f"Connected to MCP server '{server_name}'. "
|
|
218
|
-
f"{num_tools} tools are now available."
|
|
219
|
-
f"{tool_descriptions}"
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
except Exception as e:
|
|
223
|
-
logger.error(f"Error connecting to server '{server_name}': {e}")
|
|
224
|
-
return f"Failed to connect to server '{server_name}': {str(e)}"
|
|
225
|
-
|
|
226
|
-
async def get_active_server(self) -> str:
|
|
227
|
-
"""Get the currently active MCP server.
|
|
228
|
-
|
|
229
|
-
Returns:
|
|
230
|
-
Name of the active server or message if none is active
|
|
231
|
-
"""
|
|
232
|
-
if not self.active_server:
|
|
233
|
-
return (
|
|
234
|
-
"No MCP server is currently active. "
|
|
235
|
-
"Use connect_to_mcp_server to connect to a server."
|
|
236
|
-
)
|
|
237
|
-
return f"Currently active MCP server: {self.active_server}"
|
|
238
|
-
|
|
239
|
-
async def disconnect_from_server(self) -> str:
|
|
240
|
-
"""Disconnect from the currently active MCP server.
|
|
241
|
-
|
|
242
|
-
Returns:
|
|
243
|
-
Status message about the disconnection
|
|
244
|
-
"""
|
|
245
|
-
|
|
246
|
-
if not self.active_server:
|
|
247
|
-
return "No MCP server is currently active, so there's nothing to disconnect from."
|
|
248
|
-
|
|
249
|
-
server_name = self.active_server
|
|
250
|
-
try:
|
|
251
|
-
# Clear the active server
|
|
252
|
-
self.active_server = None
|
|
253
|
-
|
|
254
|
-
# Note: We're not actually closing the session here, just 'deactivating'
|
|
255
|
-
# This way we keep the session cache without requiring reconnection if needed again
|
|
256
|
-
# TODO: consider closing the sessions
|
|
257
|
-
|
|
258
|
-
return f"Successfully disconnected from MCP server '{server_name}'."
|
|
259
|
-
except Exception as e:
|
|
260
|
-
logger.error(f"Error disconnecting from server '{server_name}': {e}")
|
|
261
|
-
return f"Failed to disconnect from server '{server_name}': {str(e)}"
|
|
262
|
-
|
|
263
|
-
async def get_active_server_tools(self) -> list[BaseTool]:
|
|
264
|
-
"""Get the tools for the currently active server.
|
|
265
|
-
|
|
266
|
-
Returns:
|
|
267
|
-
List of LangChain tools for the active server or empty list if no active server
|
|
268
|
-
"""
|
|
269
|
-
if not self.active_server:
|
|
270
|
-
return []
|
|
271
|
-
|
|
272
|
-
return self._server_tools.get(self.active_server, [])
|
|
273
|
-
|
|
274
|
-
async def get_all_tools(self) -> list[BaseTool]:
|
|
275
|
-
"""Get all tools - both server management tools and tools for the active server.
|
|
276
|
-
|
|
277
|
-
Returns:
|
|
278
|
-
Combined list of server management tools and active server tools
|
|
279
|
-
"""
|
|
280
|
-
management_tools = await self.get_server_management_tools()
|
|
281
|
-
active_server_tools = await self.get_active_server_tools()
|
|
282
|
-
return management_tools + active_server_tools
|
|
File without changes
|
|
File without changes
|