mcp-haystack 1.5.0__tar.gz → 1.5.2__tar.gz
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.
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/CHANGELOG.md +22 -1
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/PKG-INFO +1 -1
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/mcp_tool.py +4 -1
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/mcp_toolset.py +5 -1
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_mcp_tool.py +15 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_mcp_toolset.py +20 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/.gitignore +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/LICENSE.txt +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/README.md +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/mcp_client.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/mcp_filtered_tools.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/mcp_server.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/mcp_stdio_client.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/mcp_stdio_toolset.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/time_pipeline.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/examples/time_pipeline_toolset.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/pydoc/config_docusaurus.yml +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/pyproject.toml +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/__init__.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/compatibility_layer.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/py.typed +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/__init__.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/conftest.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/mcp_memory_transport.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/mcp_servers_fixtures.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_compatibility_layer.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_mcp_integration.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_mcp_server_info.py +0 -0
- {mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/tests/test_mcp_timeout_reconnection.py +0 -0
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/mcp-v1.5.1] - 2026-09-01
|
|
4
|
+
|
|
5
|
+
### 🚀 Features
|
|
6
|
+
|
|
7
|
+
- Support MCP Python SDK v2 - compatibility mode (#3878)
|
|
8
|
+
|
|
9
|
+
### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- Standardize license files (#3771)
|
|
12
|
+
|
|
13
|
+
### 🧪 Testing
|
|
14
|
+
|
|
15
|
+
- MCP - refactor test_toolset_combination for Toolset.__add__ removal (#3877)
|
|
16
|
+
|
|
17
|
+
### 🧹 Chores
|
|
18
|
+
|
|
19
|
+
- Re-standardize READMEs (#3768)
|
|
20
|
+
|
|
21
|
+
|
|
3
22
|
## [integrations/mcp-v1.4.1] - 2026-07-29
|
|
4
23
|
|
|
5
24
|
### 🐛 Bug Fixes
|
|
@@ -103,7 +122,7 @@
|
|
|
103
122
|
|
|
104
123
|
- Add MCPTool/MCPToolset warm_up (#2384)
|
|
105
124
|
|
|
106
|
-
## [integrations/mcp-v0.8
|
|
125
|
+
## [integrations/mcp-v0.0.8] - 2025-10-14
|
|
107
126
|
|
|
108
127
|
### 🐛 Bug Fixes
|
|
109
128
|
|
|
@@ -160,6 +179,8 @@
|
|
|
160
179
|
|
|
161
180
|
- Align core-integrations Hatch scripts (#1898)
|
|
162
181
|
|
|
182
|
+
## [integrations/mcp-v0.3.1] - 2025-05-28
|
|
183
|
+
|
|
163
184
|
### 🌀 Miscellaneous
|
|
164
185
|
|
|
165
186
|
- App pins for MCP (#1845)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: mcp-haystack
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: Haystack integration for Model Context Protocol (MCP)
|
|
5
5
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/mcp#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
@@ -1155,7 +1155,7 @@ class MCPTool(Tool):
|
|
|
1155
1155
|
return set(properties.keys())
|
|
1156
1156
|
|
|
1157
1157
|
def warm_up(self) -> None:
|
|
1158
|
-
"""Connect and fetch the tool schema
|
|
1158
|
+
"""Connect and fetch the tool schema unless already connected."""
|
|
1159
1159
|
with self._lock:
|
|
1160
1160
|
if self._client is not None:
|
|
1161
1161
|
return
|
|
@@ -1266,6 +1266,9 @@ class MCPTool(Tool):
|
|
|
1266
1266
|
self._worker.stop()
|
|
1267
1267
|
except Exception as e:
|
|
1268
1268
|
logger.debug(f"TOOL: Error during synchronous worker stop: {e!s}")
|
|
1269
|
+
finally:
|
|
1270
|
+
self._client = None
|
|
1271
|
+
self._worker = None
|
|
1269
1272
|
|
|
1270
1273
|
def __del__(self) -> None:
|
|
1271
1274
|
"""Cleanup resources when the tool is garbage collected."""
|
{mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/mcp_toolset.py
RENAMED
|
@@ -244,6 +244,7 @@ class MCPToolset(Toolset):
|
|
|
244
244
|
self.outputs_to_state = outputs_to_state or {}
|
|
245
245
|
self.outputs_to_string = outputs_to_string or {}
|
|
246
246
|
self._warmup_called = False
|
|
247
|
+
self._worker: _MCPClientSessionManager | None = None
|
|
247
248
|
|
|
248
249
|
if not eager_connect:
|
|
249
250
|
# Do not connect during validation; expose a toolset with one fake tool to pass validation
|
|
@@ -261,7 +262,7 @@ class MCPToolset(Toolset):
|
|
|
261
262
|
|
|
262
263
|
def warm_up(self) -> None:
|
|
263
264
|
"""
|
|
264
|
-
Connect and load tools
|
|
265
|
+
Connect and load tools unless already connected.
|
|
265
266
|
|
|
266
267
|
This method is automatically called by `Agent.warm_up()` and `Pipeline.warm_up()`.
|
|
267
268
|
You can also call it directly before using the toolset to ensure all tool schemas
|
|
@@ -511,6 +512,9 @@ class MCPToolset(Toolset):
|
|
|
511
512
|
self._worker.stop()
|
|
512
513
|
except Exception as e:
|
|
513
514
|
logger.debug(f"TOOLSET: error during worker stop: {e!s}")
|
|
515
|
+
finally:
|
|
516
|
+
self._worker = None
|
|
517
|
+
self._warmup_called = False
|
|
514
518
|
|
|
515
519
|
def __del__(self) -> None:
|
|
516
520
|
self.close()
|
|
@@ -17,6 +17,7 @@ from haystack.tools.from_function import tool
|
|
|
17
17
|
from haystack_integrations.tools.mcp import (
|
|
18
18
|
MCPTool,
|
|
19
19
|
MCPToolNotFoundError,
|
|
20
|
+
SSEServerInfo,
|
|
20
21
|
StdioServerInfo,
|
|
21
22
|
)
|
|
22
23
|
from haystack_integrations.tools.mcp.mcp_tool import (
|
|
@@ -365,6 +366,20 @@ class TestMCPTool:
|
|
|
365
366
|
assert "b" in tool.parameters["properties"]
|
|
366
367
|
assert mock_connect.call_count == 1
|
|
367
368
|
|
|
369
|
+
@pytest.mark.parametrize("eager_connect", [False, True])
|
|
370
|
+
def test_mcp_tool_reopens_after_close(self, eager_connect, mcp_calculator_server, mcp_tool_cleanup):
|
|
371
|
+
port = mcp_calculator_server("sse")
|
|
372
|
+
server_info = SSEServerInfo(url=f"http://127.0.0.1:{port}/sse", max_retries=0)
|
|
373
|
+
tool = mcp_tool_cleanup(MCPTool(name="add", server_info=server_info, eager_connect=eager_connect))
|
|
374
|
+
|
|
375
|
+
tool.warm_up()
|
|
376
|
+
assert json.loads(tool.invoke(a=2, b=3))["content"][0]["text"] == "5"
|
|
377
|
+
|
|
378
|
+
tool.close()
|
|
379
|
+
|
|
380
|
+
tool.warm_up()
|
|
381
|
+
assert json.loads(tool.invoke(a=2, b=3))["content"][0]["text"] == "5"
|
|
382
|
+
|
|
368
383
|
@pytest.mark.asyncio
|
|
369
384
|
async def test_mcp_tool_ainvoke_matches_invoke_with_outputs_to_state(self, mcp_tool_cleanup):
|
|
370
385
|
"""Test that sync and async invocation paths return the same parsed state output."""
|
|
@@ -195,6 +195,26 @@ class TestMCPToolset:
|
|
|
195
195
|
toolset.warm_up()
|
|
196
196
|
assert [tool.name for tool in toolset.tools] == warmed_tool_names
|
|
197
197
|
|
|
198
|
+
@pytest.mark.parametrize("eager_connect", [False, True])
|
|
199
|
+
async def test_mcp_toolset_reopens_after_close(self, eager_connect, mcp_calculator_server, mcp_tool_cleanup):
|
|
200
|
+
port = mcp_calculator_server("sse")
|
|
201
|
+
server_info = SSEServerInfo(url=f"http://127.0.0.1:{port}/sse", max_retries=0)
|
|
202
|
+
toolset = mcp_tool_cleanup(MCPToolset(server_info=server_info, eager_connect=eager_connect))
|
|
203
|
+
|
|
204
|
+
toolset.warm_up()
|
|
205
|
+
assert sorted(tool.name for tool in toolset.tools) == ["add", "subtract"]
|
|
206
|
+
for tool in toolset.tools:
|
|
207
|
+
expected = "5" if tool.name == "add" else "-1"
|
|
208
|
+
assert json.loads(tool.invoke(a=2, b=3))["content"][0]["text"] == expected
|
|
209
|
+
|
|
210
|
+
toolset.close()
|
|
211
|
+
|
|
212
|
+
toolset.warm_up()
|
|
213
|
+
assert sorted(tool.name for tool in toolset.tools) == ["add", "subtract"]
|
|
214
|
+
for tool in toolset.tools:
|
|
215
|
+
expected = "5" if tool.name == "add" else "-1"
|
|
216
|
+
assert json.loads(tool.invoke(a=2, b=3))["content"][0]["text"] == expected
|
|
217
|
+
|
|
198
218
|
async def test_toolset_serde(self, calculator_toolset):
|
|
199
219
|
"""Test serialization and deserialization of MCPToolset."""
|
|
200
220
|
toolset = calculator_toolset
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_haystack-1.5.0 → mcp_haystack-1.5.2}/src/haystack_integrations/tools/mcp/compatibility_layer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|