mcp-use 1.3.6__py3-none-any.whl → 1.3.8__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.

@@ -8,6 +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
12
 
12
13
  from ..logging import logger
13
14
  from ..task_managers import StdioConnectionManager
@@ -28,6 +29,8 @@ class StdioConnector(BaseConnector):
28
29
  args: list[str] | None = None,
29
30
  env: dict[str, str] | None = None,
30
31
  errlog=sys.stderr,
32
+ sampling_callback: SamplingFnT | None = None,
33
+ elicitation_callback: ElicitationFnT | None = None,
31
34
  ):
32
35
  """Initialize a new stdio connector.
33
36
 
@@ -36,8 +39,10 @@ class StdioConnector(BaseConnector):
36
39
  args: Optional command line arguments.
37
40
  env: Optional environment variables.
38
41
  errlog: Stream to write error output to.
42
+ sampling_callback: Optional callback to sample the client.
43
+ elicitation_callback: Optional callback to elicit the client.
39
44
  """
40
- super().__init__()
45
+ super().__init__(sampling_callback=sampling_callback, elicitation_callback=elicitation_callback)
41
46
  self.command = command
42
47
  self.args = args or [] # Ensure args is never None
43
48
  self.env = env
@@ -59,7 +64,13 @@ class StdioConnector(BaseConnector):
59
64
  read_stream, write_stream = await self._connection_manager.start()
60
65
 
61
66
  # Create the client session
62
- self.client_session = ClientSession(read_stream, write_stream, sampling_callback=None)
67
+ self.client_session = ClientSession(
68
+ read_stream,
69
+ write_stream,
70
+ sampling_callback=self.sampling_callback,
71
+ elicitation_callback=self.elicitation_callback,
72
+ client_info=self.client_info,
73
+ )
63
74
  await self.client_session.__aenter__()
64
75
 
65
76
  # Mark as connected
@@ -6,16 +6,14 @@ from .tools import (
6
6
  ListServersTool,
7
7
  MCPServerTool,
8
8
  SearchToolsTool,
9
- UseToolFromServerTool,
10
9
  )
11
10
 
12
11
  __all__ = [
13
12
  "ServerManager",
14
- "ListServersTool",
13
+ "MCPServerTool",
15
14
  "ConnectServerTool",
16
- "GetActiveServerTool",
17
15
  "DisconnectServerTool",
16
+ "GetActiveServerTool",
17
+ "ListServersTool",
18
18
  "SearchToolsTool",
19
- "MCPServerTool",
20
- "UseToolFromServerTool",
21
19
  ]
@@ -10,7 +10,6 @@ from .tools import (
10
10
  GetActiveServerTool,
11
11
  ListServersTool,
12
12
  SearchToolsTool,
13
- UseToolFromServerTool,
14
13
  )
15
14
 
16
15
 
@@ -73,12 +72,21 @@ class ServerManager:
73
72
  except Exception as e:
74
73
  logger.error(f"Error prefetching tools for server '{server_name}': {e}")
75
74
 
76
- @property
77
- def tools(self) -> list[BaseTool]:
78
- """Get all server management tools.
75
+ def get_active_server_tools(self) -> list[BaseTool]:
76
+ """Get tools from the currently active server.
77
+
78
+ Returns:
79
+ List of tools from the active server, or empty list if no server is active
80
+ """
81
+ if self.active_server and self.active_server in self._server_tools:
82
+ return self._server_tools[self.active_server]
83
+ return []
84
+
85
+ def get_management_tools(self) -> list[BaseTool]:
86
+ """Get the server management tools.
79
87
 
80
88
  Returns:
81
- list of LangChain tools for server management
89
+ List of server management tools
82
90
  """
83
91
  return [
84
92
  ListServersTool(self),
@@ -86,5 +94,36 @@ class ServerManager:
86
94
  GetActiveServerTool(self),
87
95
  DisconnectServerTool(self),
88
96
  SearchToolsTool(self),
89
- UseToolFromServerTool(self),
90
97
  ]
98
+
99
+ def has_tool_changes(self, current_tool_names: set[str]) -> bool:
100
+ """Check if the available tools have changed.
101
+
102
+ Args:
103
+ current_tool_names: Set of currently known tool names
104
+
105
+ Returns:
106
+ True if tools have changed, False otherwise
107
+ """
108
+ new_tool_names = {tool.name for tool in self.tools}
109
+ return new_tool_names != current_tool_names
110
+
111
+ @property
112
+ def tools(self) -> list[BaseTool]:
113
+ """Get all server management tools and tools from the active server.
114
+
115
+ Returns:
116
+ list of LangChain tools for server management plus tools from active server
117
+ """
118
+ management_tools = self.get_management_tools()
119
+
120
+ # Add tools from the active server if available
121
+ if self.active_server and self.active_server in self._server_tools:
122
+ server_tools = self._server_tools[self.active_server]
123
+ logger.debug(f"Including {len(server_tools)} tools from active server '{self.active_server}'")
124
+ logger.debug(f"Server tools: {[tool.name for tool in server_tools]}")
125
+ return management_tools + server_tools
126
+ else:
127
+ logger.debug("No active server - returning only management tools")
128
+
129
+ return management_tools
@@ -4,14 +4,12 @@ from .disconnect_server import DisconnectServerTool
4
4
  from .get_active_server import GetActiveServerTool
5
5
  from .list_servers_tool import ListServersTool
6
6
  from .search_tools import SearchToolsTool
7
- from .use_tool import UseToolFromServerTool
8
7
 
9
8
  __all__ = [
10
9
  "MCPServerTool",
11
- "ListServersTool",
12
10
  "ConnectServerTool",
13
- "GetActiveServerTool",
14
11
  "DisconnectServerTool",
12
+ "GetActiveServerTool",
13
+ "ListServersTool",
15
14
  "SearchToolsTool",
16
- "UseToolFromServerTool",
17
15
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-use
3
- Version: 1.3.6
3
+ Version: 1.3.8
4
4
  Summary: MCP Library for LLMs
5
5
  Author-email: Pietro Zullo <pietro.zullo@gmail.com>
6
6
  License: MIT
@@ -17,7 +17,7 @@ Requires-Python: >=3.11
17
17
  Requires-Dist: aiohttp>=3.9.0
18
18
  Requires-Dist: jsonschema-pydantic>=0.1.0
19
19
  Requires-Dist: langchain>=0.1.0
20
- Requires-Dist: mcp>=1.9.3
20
+ Requires-Dist: mcp>=1.10.0
21
21
  Requires-Dist: posthog>=4.8.0
22
22
  Requires-Dist: pydantic>=2.0.0
23
23
  Requires-Dist: python-dotenv>=1.0.0
@@ -28,7 +28,7 @@ Requires-Dist: langchain-anthropic; extra == 'anthropic'
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: black>=23.9.0; extra == 'dev'
30
30
  Requires-Dist: fastapi; extra == 'dev'
31
- Requires-Dist: fastmcp==2.8.0; extra == 'dev'
31
+ Requires-Dist: fastmcp==2.10.5; extra == 'dev'
32
32
  Requires-Dist: isort>=5.12.0; extra == 'dev'
33
33
  Requires-Dist: mypy>=1.5.0; extra == 'dev'
34
34
  Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
@@ -84,12 +84,16 @@ Description-Content-Type: text/markdown
84
84
 
85
85
  💡 Let developers easily connect any LLM to tools like web browsing, file operations, and more.
86
86
 
87
- - Visit the [mcp-use.com website](https://mcp-use.com/) to know how to build and deploy MCP agents.
87
+ - If you want to get started quickly check out [mcp-use.com website](https://mcp-use.com/) to build and deploy agents with your favorite MCP servers.
88
88
  - Visit the [mcp-use docs](https://docs.mcp-use.com/) to get started with mcp-use library
89
+ - For the TypeScript version, visit [mcp-use-ts](https://github.com/mcp-use/mcp-use-ts)
89
90
 
90
- 💬 Get started quickly - chat with your servers on our <b>hosted version</b>! [Try mcp-use chat (beta)](https://chat.mcp-use.com).
91
+ | Supports | |
92
+ | :--- | :--- |
93
+ | **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) |
91
95
 
92
- # Features
96
+ ## Features
93
97
 
94
98
  <table>
95
99
  <tr>
@@ -807,45 +811,45 @@ Thanks to all our amazing contributors!
807
811
  <th width="400">Repository</th>
808
812
  <th>Stars</th>
809
813
  </tr>
814
+ <tr>
815
+ <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>
817
+ </tr>
810
818
  <tr>
811
819
  <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>
812
- <td>⭐ 112</td>
820
+ <td>⭐ 129</td>
821
+ </tr>
822
+ <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>
813
825
  </tr>
814
826
  <tr>
815
827
  <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>
816
- <td>⭐ 37</td>
828
+ <td>⭐ 58</td>
829
+ </tr>
830
+ <tr>
831
+ <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>
817
833
  </tr>
818
834
  <tr>
819
835
  <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>
820
- <td>⭐ 29</td>
836
+ <td>⭐ 30</td>
821
837
  </tr>
822
838
  <tr>
823
839
  <td><img src="https://avatars.githubusercontent.com/u/8344498?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/schogini/techietalksai"><strong>schogini/techietalksai</strong></a></td>
824
- <td>⭐ 21</td>
840
+ <td>⭐ 24</td>
825
841
  </tr>
826
842
  <tr>
827
843
  <td><img src="https://avatars.githubusercontent.com/u/201161342?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/autometa-dev/whatsapp-mcp-voice-agent"><strong>autometa-dev/whatsapp-mcp-voice-agent</strong></a></td>
828
- <td>⭐ 18</td>
844
+ <td>⭐ 22</td>
829
845
  </tr>
830
846
  <tr>
831
847
  <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>
832
- <td>⭐ 17</td>
833
- </tr>
834
- <tr>
835
- <td><img src="https://avatars.githubusercontent.com/u/6764390?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/elastic/genai-workshops"><strong>elastic/genai-workshops</strong></a></td>
836
- <td>⭐ 9</td>
848
+ <td>⭐ 18</td>
837
849
  </tr>
838
850
  <tr>
839
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>
840
- <td>⭐ 6</td>
841
- </tr>
842
- <tr>
843
- <td><img src="https://avatars.githubusercontent.com/u/205593730?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/Qingyon-AI/Revornix"><strong>Qingyon-AI/Revornix</strong></a></td>
844
- <td>⭐ 5</td>
845
- </tr>
846
- <tr>
847
- <td><img src="https://avatars.githubusercontent.com/u/68845761?s=40&v=4" width="20" height="20" style="vertical-align: middle; margin-right: 8px;"> <a href="https://github.com/entbappy/MCP-Tutorials"><strong>entbappy/MCP-Tutorials</strong></a></td>
848
- <td>⭐ 5</td>
852
+ <td>⭐ 15</td>
849
853
  </tr>
850
854
  </table>
851
855
 
@@ -1,34 +1,34 @@
1
1
  mcp_use/__init__.py,sha256=I3gFxw6Id45RksUBIZS1kxBW3ItjFXuAfoReJabpnW0,1055
2
- mcp_use/client.py,sha256=9u_GZxsyVoZY_g1dWGK8JiLmTatY6YvwGb4IM8idYZs,9391
3
- mcp_use/config.py,sha256=jRjTVNMxi7pkqFHMJhzSWpwukE4PbdYU8Pe_IZ33sYI,2433
2
+ mcp_use/client.py,sha256=dziKHIZIclLk64ycF4keegiVp93YKqSyGok7Rv4j8bE,10958
3
+ mcp_use/config.py,sha256=J3ebF9dlQxui3pSONTFtVYO035E7d0CP4HAvN0INgE4,3103
4
4
  mcp_use/logging.py,sha256=CRtkPwR-bkXK_kQ0QOL86RikMWOHzEOi7A8VRHkNsZw,4270
5
5
  mcp_use/session.py,sha256=4kwcB_IkTt_3FiBSTI1H17KhL1W_6N5oai3HTxFrTH4,2496
6
6
  mcp_use/utils.py,sha256=QavJcVq2WxUUUCCpPCUeOB5bqIS0FFmpK-RAZkGc6aA,720
7
7
  mcp_use/adapters/__init__.py,sha256=-xCrgPThuX7x0PHGFDdjb7M-mgw6QV3sKu5PM7ShnRg,275
8
8
  mcp_use/adapters/base.py,sha256=U1z_UzojC-bytb4ZuKTRpEgEp-2F_BVBgqEXbUqLYB4,6901
9
9
  mcp_use/adapters/langchain_adapter.py,sha256=LdlpRyLORhl8NZvtAmisgPelXkhEbBErSNdGHb8SF18,10860
10
- mcp_use/agents/__init__.py,sha256=N3eVYP2PxqNO2KcQv5fY8UMUX2W3eLTNkkzuFIJ1DUA,261
10
+ mcp_use/agents/__init__.py,sha256=FzkntihbAqzixWdWe99zIrrcIfd4N3YWltNniutG9VA,267
11
11
  mcp_use/agents/base.py,sha256=EN-dRbwOi9vIqofFg3jmi5yT2VKlwEr9Cwi1DZgB3eE,1591
12
- mcp_use/agents/mcpagent.py,sha256=K3gKlPvqIPiniifi46Xs82_D2YKNO-Vn4BTTH55LPbI,35753
12
+ mcp_use/agents/mcpagent.py,sha256=Vh4VOxxh-6sJwK1tTtJgUWZcp1bd3hb_JnATc7x9sKk,46698
13
+ mcp_use/agents/remote.py,sha256=_8TKP-hfr8NsexbpaEz8bK4LU-opILJMnTL7TbQBiY4,10575
13
14
  mcp_use/agents/prompts/system_prompt_builder.py,sha256=E86STmxcl2Ic763_114awNqFB2RyLrQlbvgRmJajQjI,4116
14
- mcp_use/agents/prompts/templates.py,sha256=AZKrGWuI516C-PmyOPvxDBibNdqJtN24sOHTGR06bi4,1933
15
+ mcp_use/agents/prompts/templates.py,sha256=acg2Q-_uQDL-3q5ZUwwwFrP7wqqf-SEyq0XWDDHt69s,1906
15
16
  mcp_use/connectors/__init__.py,sha256=cUF4yT0bNr8qeLkSzg28SHueiV5qDaHEB1l1GZ2K0dc,536
16
- mcp_use/connectors/base.py,sha256=GnI2WCrcxjOaB0R6Hj9pTpAZ0I1YRwkz1gGt-tvuZa0,12609
17
- mcp_use/connectors/http.py,sha256=oZbLLVDNwUaY6EwK2rVnjoZEKsBLf5-AXtPvGtbMmwc,7559
18
- mcp_use/connectors/sandbox.py,sha256=cnybcNW55k-S0hUtRR1M3KcGXwnaeDMVm8wDTsfF1Mk,10875
19
- mcp_use/connectors/stdio.py,sha256=rnJoLaHf1cIjk1KqfxfSsUs-iGTJ7KZonxgIc3kXeCM,2791
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
20
21
  mcp_use/connectors/utils.py,sha256=zQ8GdNQx0Twz3by90BoU1RsWPf9wODGof4K3-NxPXeA,366
21
22
  mcp_use/connectors/websocket.py,sha256=G7ZeLJNPVl9AG6kCmiNJz1N2Ing_QxT7pSswigTKi8Y,9650
22
- mcp_use/managers/__init__.py,sha256=rzsJbOhtlmxNQLGcdmtmHaiExEXmiQiUuzPrAgKhAJw,439
23
- mcp_use/managers/server_manager.py,sha256=Ag1EUSxkG6-UG004vcvaZarPoDnUUMMX7BUeKReUWRI,3704
24
- mcp_use/managers/tools/__init__.py,sha256=JrA5iTRdtbgwROJE8pQ7GH1sYnqBRcgj4NzFVADKbQ4,510
23
+ mcp_use/managers/__init__.py,sha256=FRTuJw5kYtY1Eo7wN9Aeqeqo1euiR5slvrx5Fl_SGvk,383
24
+ mcp_use/managers/server_manager.py,sha256=8F6jEwZOoAfR1y1O7zk-BSZ1LVYcLZTSQZLRClhSE2I,5278
25
+ mcp_use/managers/tools/__init__.py,sha256=zcpm4HXsp8NUMRJeyT6DdB8cgIMDs46pBfoTD-odhGU,437
25
26
  mcp_use/managers/tools/base_tool.py,sha256=Jbbp7SwmHKDk8jT_6yVIv7iNsn6KaV_PljWuhhLcbXg,509
26
27
  mcp_use/managers/tools/connect_server.py,sha256=MGYQCl11q-w6gSIYuT44dDk7ILV3Oh7kGAJ4fsNXbso,2923
27
28
  mcp_use/managers/tools/disconnect_server.py,sha256=Y3kJN31efzsjfJwxUhpBxS-bgU21DCfGbn_LgEbzyvI,1586
28
29
  mcp_use/managers/tools/get_active_server.py,sha256=tCaib76gYU3L5G82tEOTq4Io2cuCXWjOjPselb-92i8,964
29
30
  mcp_use/managers/tools/list_servers_tool.py,sha256=OPDSMNe-VuAhlUyhDnR4CiuZFpoMhnhWpAablwO5S0k,1897
30
31
  mcp_use/managers/tools/search_tools.py,sha256=4vso7ln-AfG6lQAMq9FA_CyeVtSEDYEWlHtdHtfnLps,12911
31
- mcp_use/managers/tools/use_tool.py,sha256=gMNjgJrI9XDitPyJglcJcAvowbEWkO5z57yt4DT2Lpc,6626
32
32
  mcp_use/observability/__init__.py,sha256=kTUcP0d6L5_3ktfldhdAk-3AWckzVHs7ztG-R6cye64,186
33
33
  mcp_use/observability/laminar.py,sha256=WWjmVXP55yCfAlqlayeuJmym1gdrv8is7UyrIp4Tbn0,839
34
34
  mcp_use/observability/langfuse.py,sha256=9vgJgnGtVpv_CbCyJqyRkzq2ELqPfYFIUGnpSbm2RCo,1334
@@ -43,7 +43,7 @@ mcp_use/telemetry/events.py,sha256=K5xqbmkum30r4gM2PWtTiUWGF8oZzGZw2DYwco1RfOQ,3
43
43
  mcp_use/telemetry/telemetry.py,sha256=ck2MDFMtooafriR1W_zi41dWq-0O-ucF89pCkdkyc9E,11724
44
44
  mcp_use/telemetry/utils.py,sha256=kDVTqt2oSeWNJbnTOlXOehr2yFO0PMyx2UGkrWkfJiw,1769
45
45
  mcp_use/types/sandbox.py,sha256=opJ9r56F1FvaqVvPovfAj5jZbsOexgwYx5wLgSlN8_U,712
46
- mcp_use-1.3.6.dist-info/METADATA,sha256=Mm5tZfT6AQmckx_9d75uLPYwVaM2K_a4MG4L64DPblY,28534
47
- mcp_use-1.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
48
- mcp_use-1.3.6.dist-info/licenses/LICENSE,sha256=7Pw7dbwJSBw8zH-WE03JnR5uXvitRtaGTP9QWPcexcs,1068
49
- mcp_use-1.3.6.dist-info/RECORD,,
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,,
@@ -1,154 +0,0 @@
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(self, server_name: str, tool_name: str, tool_input: dict[str, Any] | str) -> str:
34
- """Execute a tool from a specific server."""
35
- # Check if server exists
36
- servers = self.server_manager.client.get_server_names()
37
- if server_name not in servers:
38
- available = ", ".join(servers) if servers else "none"
39
- return f"Server '{server_name}' not found. Available servers: {available}"
40
-
41
- # Connect to the server if not already connected or not the active server
42
- is_connected = server_name == self.server_manager.active_server
43
-
44
- if not is_connected:
45
- try:
46
- # Create or get session for this server
47
- try:
48
- session = self.server_manager.client.get_session(server_name)
49
- logger.debug(f"Using existing session for server '{server_name}'")
50
- except ValueError:
51
- logger.debug(f"Creating new session for server '{server_name}' for tool use")
52
- session = await self.server_manager.client.create_session(server_name)
53
-
54
- # Check if we have tools for this server, if not get them
55
- if server_name not in self.server_manager._server_tools:
56
- connector = session.connector
57
- self.server_manager._server_tools[
58
- server_name
59
- ] = await self.server_manager.adapter._create_tools_from_connectors([connector])
60
- self.server_manager.initialized_servers[server_name] = True
61
- except Exception as e:
62
- logger.error(f"Error connecting to server '{server_name}' for tool use: {e}")
63
- return f"Failed to connect to server '{server_name}': {str(e)}"
64
-
65
- # Get tools for the server
66
- server_tools = self.server_manager._server_tools.get(server_name, [])
67
- if not server_tools:
68
- return f"No tools found for server '{server_name}'"
69
-
70
- # Find the requested tool
71
- target_tool = None
72
- for tool in server_tools:
73
- if tool.name == tool_name:
74
- target_tool = tool
75
- break
76
-
77
- if not target_tool:
78
- tool_names = [t.name for t in server_tools]
79
- return f"Tool '{tool_name}' not found on server '{server_name}'. Available tools: {', '.join(tool_names)}"
80
-
81
- # Execute the tool with the provided input
82
- try:
83
- # Parse the input based on target tool's schema
84
- structured_input = self._parse_tool_input(target_tool, tool_input)
85
- if structured_input is None:
86
- return f"Could not parse input for tool '{tool_name}'. Please check the input format and try again."
87
-
88
- # Store the previous active server
89
- previous_active = self.server_manager.active_server
90
-
91
- # Temporarily set this server as active
92
- self.server_manager.active_server = server_name
93
-
94
- # Execute the tool
95
- logger.info(f"Executing tool '{tool_name}' on server '{server_name}'with input: {{structured_input}}")
96
- result = await target_tool._arun(**structured_input)
97
-
98
- # Restore the previous active server
99
- self.server_manager.active_server = previous_active
100
-
101
- return result
102
-
103
- except Exception as e:
104
- logger.error(f"Error executing tool '{tool_name}' on server '{server_name}': {e}")
105
- return (
106
- f"Error executing tool '{tool_name}' on server '{server_name}': {str(e)}. "
107
- f"Make sure the input format is correct for this tool."
108
- )
109
-
110
- def _parse_tool_input(self, tool: BaseTool, input_data: dict[str, Any] | str) -> dict[str, Any]:
111
- """
112
- Parse the input data according to the tool's schema.
113
-
114
- Args:
115
- tool: The target tool
116
- input_data: The input data, either a dictionary or a string
117
-
118
- Returns:
119
- A dictionary with properly structured input for the tool
120
- """
121
- # If input is already a dict, use it directly
122
- if isinstance(input_data, dict):
123
- return input_data
124
-
125
- # Try to parse as JSON first
126
- if isinstance(input_data, str):
127
- try:
128
- return json.loads(input_data)
129
- except json.JSONDecodeError:
130
- pass
131
-
132
- # For string input, we need to determine which parameter name to use
133
- if hasattr(tool, "args_schema") and tool.args_schema:
134
- schema_cls = tool.args_schema
135
- field_names = list(schema_cls.__fields__.keys())
136
-
137
- # If schema has only one field, use that
138
- if len(field_names) == 1:
139
- return {field_names[0]: input_data}
140
-
141
- # Look for common input field names
142
- for name in field_names:
143
- if name.lower() in ["input", "query", "url", tool.name.lower()]:
144
- return {name: input_data}
145
-
146
- # Default to first field if we can't determine
147
- return {field_names[0]: input_data}
148
-
149
- # If we get here something went wrong
150
- return None
151
-
152
- def _run(self, server_name: str, tool_name: str, tool_input: dict[str, Any] | str) -> str:
153
- """Synchronous version that raises a NotImplementedError."""
154
- raise NotImplementedError("UseToolFromServerTool requires async execution. Use _arun instead.")