langchain-mcp-tools 0.1.0__py3-none-any.whl → 0.1.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.
- langchain_mcp_tools/langchain_mcp_tools.py +18 -3
- {langchain_mcp_tools-0.1.0.dist-info → langchain_mcp_tools-0.1.1.dist-info}/METADATA +4 -3
- langchain_mcp_tools-0.1.1.dist-info/RECORD +8 -0
- langchain_mcp_tools-0.1.0.dist-info/RECORD +0 -8
- {langchain_mcp_tools-0.1.0.dist-info → langchain_mcp_tools-0.1.1.dist-info}/LICENSE +0 -0
- {langchain_mcp_tools-0.1.0.dist-info → langchain_mcp_tools-0.1.1.dist-info}/WHEEL +0 -0
- {langchain_mcp_tools-0.1.0.dist-info → langchain_mcp_tools-0.1.1.dist-info}/top_level.txt +0 -0
@@ -50,7 +50,8 @@ The key aspects are:
|
|
50
50
|
- Initializing multiple MCP servers in parallel requires a dedicated
|
51
51
|
`asyncio.Task` per server
|
52
52
|
- Server cleanup can be initiated later by a task other than the one that
|
53
|
-
initialized the resources
|
53
|
+
initialized the resources, whereas `AsyncExitStack.aclose()` must be
|
54
|
+
called from the same task that created the context
|
54
55
|
|
55
56
|
2. Solution:
|
56
57
|
|
@@ -151,12 +152,16 @@ async def spawn_mcp_server_tools_task(
|
|
151
152
|
env=env
|
152
153
|
)
|
153
154
|
|
155
|
+
# Use an intermediate `asynccontextmanager` to log the cleanup message
|
154
156
|
@asynccontextmanager
|
155
157
|
async def log_before_aexit(context_manager, message):
|
156
158
|
yield await context_manager.__aenter__()
|
157
|
-
|
158
|
-
|
159
|
+
try:
|
160
|
+
logger.info(message)
|
161
|
+
finally:
|
162
|
+
await context_manager.__aexit__(None, None, None)
|
159
163
|
|
164
|
+
# Initialize the MCP server
|
160
165
|
exit_stack = AsyncExitStack()
|
161
166
|
|
162
167
|
stdio_transport = await exit_stack.enter_async_context(
|
@@ -174,8 +179,10 @@ async def spawn_mcp_server_tools_task(
|
|
174
179
|
await session.initialize()
|
175
180
|
logger.info(f'MCP server "{server_name}": connected')
|
176
181
|
|
182
|
+
# Get MCP tools
|
177
183
|
tools_response = await session.list_tools()
|
178
184
|
|
185
|
+
# Wrap MCP tools to into LangChain tools
|
179
186
|
for tool in tools_response.tools:
|
180
187
|
class McpToLangChainAdapter(BaseTool):
|
181
188
|
name: str = tool.name or 'NO NAME'
|
@@ -211,10 +218,13 @@ async def spawn_mcp_server_tools_task(
|
|
211
218
|
logger.error(f'Error getting response: {str(e)}')
|
212
219
|
raise
|
213
220
|
|
221
|
+
# Set ready_event; signals tools are ready
|
214
222
|
ready_event.set()
|
215
223
|
|
224
|
+
# Keep this task alive until cleanup is requested
|
216
225
|
await cleanup_event.wait()
|
217
226
|
|
227
|
+
# Cleanup the resources
|
218
228
|
await exit_stack.aclose()
|
219
229
|
|
220
230
|
|
@@ -258,6 +268,7 @@ async def convert_mcp_to_langchain_tools(
|
|
258
268
|
ready_event_list = []
|
259
269
|
cleanup_event_list = []
|
260
270
|
|
271
|
+
# Concurrently initialize all the MCP servers
|
261
272
|
tasks = []
|
262
273
|
for server_name, server_config in server_configs.items():
|
263
274
|
server_tools_accumulator: List[BaseTool] = []
|
@@ -276,12 +287,16 @@ async def convert_mcp_to_langchain_tools(
|
|
276
287
|
))
|
277
288
|
tasks.append(task)
|
278
289
|
|
290
|
+
# Wait for all tasks to finish filling in the `server_tools_accumulator`
|
279
291
|
await asyncio.gather(*(event.wait() for event in ready_event_list))
|
280
292
|
|
293
|
+
# Flatten the tools list
|
281
294
|
langchain_tools = [
|
282
295
|
item for sublist in per_server_tools for item in sublist
|
283
296
|
]
|
284
297
|
|
298
|
+
# Define a cleanup callback to set cleanup_event and signal that
|
299
|
+
# it is time to clean up the resources
|
285
300
|
async def mcp_cleanup() -> None:
|
286
301
|
for event in cleanup_event_list:
|
287
302
|
event.set()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: langchain-mcp-tools
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.1
|
4
4
|
Summary: Model Context Protocol (MCP) To LangChain Tools Conversion Utility
|
5
5
|
Project-URL: Bug Tracker, https://github.com/hideya/langchain-mcp-tools-py/issues
|
6
6
|
Project-URL: Source Code, https://github.com/hideya/langchain-mcp-tools-py
|
@@ -28,7 +28,7 @@ This package is intended to simplify the use of
|
|
28
28
|
server tools with LangChain / Python.
|
29
29
|
|
30
30
|
It contains a utility function `convert_mcp_to_langchain_tools()`.
|
31
|
-
This function handles parallel initialization of specified multiple MCP servers
|
31
|
+
This async function handles parallel initialization of specified multiple MCP servers
|
32
32
|
and converts their available tools into a list of LangChain-compatible tools.
|
33
33
|
|
34
34
|
A typescript equivalent of this utility library is available
|
@@ -130,7 +130,8 @@ Any comments pointing out something I am missing would be greatly appreciated!
|
|
130
130
|
- Initializing multiple MCP servers in parallel requires a dedicated
|
131
131
|
`asyncio.Task` per server
|
132
132
|
- Server cleanup can be initiated later by a task other than the one
|
133
|
-
that initialized the resources
|
133
|
+
that initialized the resources, whereas `AsyncExitStack.aclose()` must be
|
134
|
+
called from the same task that created the context
|
134
135
|
|
135
136
|
2. Solution:
|
136
137
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
langchain_mcp_tools/__init__.py,sha256=Xtv2VphhrWB_KlxTIofHZqtCIGtNEl0MxugnrNXTERA,94
|
2
|
+
langchain_mcp_tools/langchain_mcp_tools.py,sha256=fBswDX7s7mY5w5DEVMB6ObuUboNivy1_hbyaN4X07ls,11104
|
3
|
+
langchain_mcp_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
langchain_mcp_tools-0.1.1.dist-info/LICENSE,sha256=CRC91e8v116gCpnp7h49oIa6_zjhxqnHFTREeoZFJwA,1072
|
5
|
+
langchain_mcp_tools-0.1.1.dist-info/METADATA,sha256=RNN7QFR1lQ5QBg4pnRQWRymoj4IKSY8GxmQpkPefzA4,6899
|
6
|
+
langchain_mcp_tools-0.1.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
7
|
+
langchain_mcp_tools-0.1.1.dist-info/top_level.txt,sha256=aR_9V2A1Yt-Bca60KmndmGLUWb2wiM5IOG-Gkaf1dxY,20
|
8
|
+
langchain_mcp_tools-0.1.1.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
langchain_mcp_tools/__init__.py,sha256=Xtv2VphhrWB_KlxTIofHZqtCIGtNEl0MxugnrNXTERA,94
|
2
|
-
langchain_mcp_tools/langchain_mcp_tools.py,sha256=PxkOAwQ8WUd12N-hZNfy2u5hawvhlEQhs0CsyPTWch0,10374
|
3
|
-
langchain_mcp_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
langchain_mcp_tools-0.1.0.dist-info/LICENSE,sha256=CRC91e8v116gCpnp7h49oIa6_zjhxqnHFTREeoZFJwA,1072
|
5
|
-
langchain_mcp_tools-0.1.0.dist-info/METADATA,sha256=FuNglrw844NXdrNWNgkK7WNIUIIdW7a1sdJKRSmdT4o,6794
|
6
|
-
langchain_mcp_tools-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
7
|
-
langchain_mcp_tools-0.1.0.dist-info/top_level.txt,sha256=aR_9V2A1Yt-Bca60KmndmGLUWb2wiM5IOG-Gkaf1dxY,20
|
8
|
-
langchain_mcp_tools-0.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|