@@ -590,4 +590,82 @@ def test_call_tool_sync_embedded_nested_base64_textual_mime(mock_transport, mock
590590 mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None )
591591 assert result ["status" ] == "success"
592592 assert len (result ["content" ]) == 1
593- assert result ["content" ][0 ]["text" ] == '{"k":"v"}'
593+ assert result ["content" ][0 ]["text" ] == '{"k":"v"}'
594+
595+
596+ def test_call_tool_sync_embedded_image_blob (mock_transport , mock_session ):
597+ """EmbeddedResource.resource (blob with image MIME) should map to image content."""
598+ import base64
599+ # Create a simple 1x1 PNG image
600+ png_data = base64 .b64decode ("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==" )
601+ payload = base64 .b64encode (png_data ).decode ()
602+
603+ er = {
604+ "type" : "resource" ,
605+ "resource" : {
606+ "uri" : "mcp://resource/embedded-image" ,
607+ "blob" : payload ,
608+ "mimeType" : "image/png" ,
609+ },
610+ }
611+ mock_session .call_tool .return_value = MCPCallToolResult (isError = False , content = [er ])
612+
613+ from strands .tools .mcp import MCPClient
614+ with MCPClient (mock_transport ["transport_callable" ]) as client :
615+ result = client .call_tool_sync (tool_use_id = "er-image" , name = "get_file_contents" , arguments = {})
616+
617+ mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None )
618+ assert result ["status" ] == "success"
619+ assert len (result ["content" ]) == 1
620+ assert "image" in result ["content" ][0 ]
621+ assert result ["content" ][0 ]["image" ]["format" ] == "png"
622+ assert "bytes" in result ["content" ][0 ]["image" ]["source" ]
623+
624+
625+ def test_call_tool_sync_embedded_non_textual_blob_dropped (mock_transport , mock_session ):
626+ """EmbeddedResource.resource (blob with non-textual/unknown MIME) should be dropped."""
627+ payload = base64 .b64encode (b'\x00 \x01 \x02 \x03 ' ).decode ()
628+
629+ er = {
630+ "type" : "resource" ,
631+ "resource" : {
632+ "uri" : "mcp://resource/embedded-binary" ,
633+ "blob" : payload ,
634+ "mimeType" : "application/octet-stream" ,
635+ },
636+ }
637+ mock_session .call_tool .return_value = MCPCallToolResult (isError = False , content = [er ])
638+
639+ from strands .tools .mcp import MCPClient
640+ with MCPClient (mock_transport ["transport_callable" ]) as client :
641+ result = client .call_tool_sync (tool_use_id = "er-binary" , name = "get_file_contents" , arguments = {})
642+
643+ mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None )
644+ assert result ["status" ] == "success"
645+ assert len (result ["content" ]) == 0 # Content should be dropped
646+
647+
648+ def test_call_tool_sync_embedded_multiple_textual_mimes (mock_transport , mock_session ):
649+ """EmbeddedResource with different textual MIME types should decode to text."""
650+ import base64
651+
652+ # Test YAML content
653+ yaml_content = base64 .b64encode (b'key: value\n list:\n - item1\n - item2' ).decode ()
654+ er = {
655+ "type" : "resource" ,
656+ "resource" : {
657+ "uri" : "mcp://resource/embedded-yaml" ,
658+ "blob" : yaml_content ,
659+ "mimeType" : "application/yaml" ,
660+ },
661+ }
662+ mock_session .call_tool .return_value = MCPCallToolResult (isError = False , content = [er ])
663+
664+ from strands .tools .mcp import MCPClient
665+ with MCPClient (mock_transport ["transport_callable" ]) as client :
666+ result = client .call_tool_sync (tool_use_id = "er-yaml" , name = "get_file_contents" , arguments = {})
667+
668+ mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None )
669+ assert result ["status" ] == "success"
670+ assert len (result ["content" ]) == 1
671+ assert "key: value" in result ["content" ][0 ]["text" ]
0 commit comments