Skip to content

Commit 5f29723

Browse files
xiehustdbschmigelski
authored andcommitted
feat(tools): Add MCP resource operations
1 parent 23408b5 commit 5f29723

File tree

2 files changed

+0
-104
lines changed

2 files changed

+0
-104
lines changed

src/strands/tools/mcp/mcp_client.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -505,42 +505,6 @@ async def _read_resource_async() -> ReadResourceResult:
505505

506506
return read_resource_result
507507

508-
def subscribe_resource_sync(self, uri: AnyUrl | str) -> None:
509-
"""Synchronously subscribes to updates for a resource from the MCP server.
510-
511-
Args:
512-
uri: The URI of the resource to subscribe to
513-
"""
514-
self._log_debug_with_thread("subscribing to MCP resource: %s", uri)
515-
if not self._is_session_active():
516-
raise MCPClientInitializationError(CLIENT_SESSION_NOT_RUNNING_ERROR_MESSAGE)
517-
518-
async def _subscribe_resource_async() -> None:
519-
# Convert string to AnyUrl if needed
520-
resource_uri = AnyUrl(uri) if isinstance(uri, str) else uri
521-
await cast(ClientSession, self._background_thread_session).subscribe_resource(resource_uri)
522-
523-
self._invoke_on_background_thread(_subscribe_resource_async()).result()
524-
self._log_debug_with_thread("successfully subscribed to resource")
525-
526-
def unsubscribe_resource_sync(self, uri: AnyUrl | str) -> None:
527-
"""Synchronously unsubscribes from updates for a resource from the MCP server.
528-
529-
Args:
530-
uri: The URI of the resource to unsubscribe from
531-
"""
532-
self._log_debug_with_thread("unsubscribing from MCP resource: %s", uri)
533-
if not self._is_session_active():
534-
raise MCPClientInitializationError(CLIENT_SESSION_NOT_RUNNING_ERROR_MESSAGE)
535-
536-
async def _unsubscribe_resource_async() -> None:
537-
# Convert string to AnyUrl if needed
538-
resource_uri = AnyUrl(uri) if isinstance(uri, str) else uri
539-
await cast(ClientSession, self._background_thread_session).unsubscribe_resource(resource_uri)
540-
541-
self._invoke_on_background_thread(_unsubscribe_resource_async()).result()
542-
self._log_debug_with_thread("successfully unsubscribed from resource")
543-
544508
def list_resource_templates_sync(self, pagination_token: Optional[str] = None) -> ListResourceTemplatesResult:
545509
"""Synchronously retrieves the list of available resource templates from the MCP server.
546510

tests/strands/tools/mcp/test_mcp_client.py

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -877,74 +877,6 @@ def test_read_resource_sync_session_not_active():
877877
client.read_resource_sync("file://documents/test.txt")
878878

879879

880-
def test_subscribe_resource_sync(mock_transport, mock_session):
881-
"""Test that subscribe_resource_sync correctly subscribes to a resource."""
882-
mock_session.subscribe_resource.return_value = None
883-
884-
with MCPClient(mock_transport["transport_callable"]) as client:
885-
# Should not raise any exception
886-
client.subscribe_resource_sync("file://documents/test.txt")
887-
888-
mock_session.subscribe_resource.assert_called_once()
889-
call_args = mock_session.subscribe_resource.call_args[0]
890-
assert str(call_args[0]) == "file://documents/test.txt"
891-
892-
893-
def test_subscribe_resource_sync_with_anyurl(mock_transport, mock_session):
894-
"""Test that subscribe_resource_sync correctly handles AnyUrl input."""
895-
mock_session.subscribe_resource.return_value = None
896-
897-
with MCPClient(mock_transport["transport_callable"]) as client:
898-
uri = AnyUrl("file://documents/test.txt")
899-
client.subscribe_resource_sync(uri)
900-
901-
mock_session.subscribe_resource.assert_called_once()
902-
call_args = mock_session.subscribe_resource.call_args[0]
903-
assert str(call_args[0]) == "file://documents/test.txt"
904-
905-
906-
def test_subscribe_resource_sync_session_not_active():
907-
"""Test that subscribe_resource_sync raises an error when session is not active."""
908-
client = MCPClient(MagicMock())
909-
910-
with pytest.raises(MCPClientInitializationError, match="client session is not running"):
911-
client.subscribe_resource_sync("file://documents/test.txt")
912-
913-
914-
def test_unsubscribe_resource_sync(mock_transport, mock_session):
915-
"""Test that unsubscribe_resource_sync correctly unsubscribes from a resource."""
916-
mock_session.unsubscribe_resource.return_value = None
917-
918-
with MCPClient(mock_transport["transport_callable"]) as client:
919-
# Should not raise any exception
920-
client.unsubscribe_resource_sync("file://documents/test.txt")
921-
922-
mock_session.unsubscribe_resource.assert_called_once()
923-
call_args = mock_session.unsubscribe_resource.call_args[0]
924-
assert str(call_args[0]) == "file://documents/test.txt"
925-
926-
927-
def test_unsubscribe_resource_sync_with_anyurl(mock_transport, mock_session):
928-
"""Test that unsubscribe_resource_sync correctly handles AnyUrl input."""
929-
mock_session.unsubscribe_resource.return_value = None
930-
931-
with MCPClient(mock_transport["transport_callable"]) as client:
932-
uri = AnyUrl("file://documents/test.txt")
933-
client.unsubscribe_resource_sync(uri)
934-
935-
mock_session.unsubscribe_resource.assert_called_once()
936-
call_args = mock_session.unsubscribe_resource.call_args[0]
937-
assert str(call_args[0]) == "file://documents/test.txt"
938-
939-
940-
def test_unsubscribe_resource_sync_session_not_active():
941-
"""Test that unsubscribe_resource_sync raises an error when session is not active."""
942-
client = MCPClient(MagicMock())
943-
944-
with pytest.raises(MCPClientInitializationError, match="client session is not running"):
945-
client.unsubscribe_resource_sync("file://documents/test.txt")
946-
947-
948880
def test_list_resource_templates_sync(mock_transport, mock_session):
949881
"""Test that list_resource_templates_sync correctly retrieves resource templates."""
950882
mock_template = ResourceTemplate(

0 commit comments

Comments
 (0)