@@ -728,8 +728,8 @@ def test_call_tool_sync_embedded_image_blob(mock_transport, mock_session):
728728 assert "bytes" in result ["content" ][0 ]["image" ]["source" ]
729729
730730
731- def test_call_tool_sync_embedded_non_textual_blob_dropped (mock_transport , mock_session ):
732- """EmbeddedResource.resource (blob with non-textual/unknown MIME) should be dropped ."""
731+ def test_call_tool_sync_embedded_non_textual_blob_falls_back_to_json (mock_transport , mock_session ):
732+ """EmbeddedResource.resource (blob with non-textual/unknown MIME) should fall back to json ."""
733733 payload = base64 .b64encode (b"\x00 \x01 \x02 \x03 " ).decode ()
734734
735735 embedded_resource = {
@@ -747,7 +747,53 @@ def test_call_tool_sync_embedded_non_textual_blob_dropped(mock_transport, mock_s
747747
748748 mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None , meta = None )
749749 assert result ["status" ] == "success"
750- assert len (result ["content" ]) == 0 # Content should be dropped
750+ assert len (result ["content" ]) == 1
751+ assert "json" in result ["content" ][0 ]
752+ assert result ["content" ][0 ]["json" ]["resource" ]["mimeType" ] == "application/octet-stream"
753+ assert result ["content" ][0 ]["json" ]["resource" ]["blob" ] == payload
754+
755+
756+ def test_call_tool_sync_image_content_unsupported_mime_falls_back_to_json (mock_transport , mock_session ):
757+ """MCPImageContent with an unsupported MIME (e.g. image/bmp) should fall back to json instead of crashing."""
758+ payload = base64 .b64encode (b"\x00 \x01 \x02 \x03 " ).decode ()
759+
760+ image_content = {
761+ "type" : "image" ,
762+ "data" : payload ,
763+ "mimeType" : "image/bmp" ,
764+ }
765+ mock_session .call_tool .return_value = MCPCallToolResult (isError = False , content = [image_content ])
766+
767+ with MCPClient (mock_transport ["transport_callable" ]) as client :
768+ result = client .call_tool_sync (tool_use_id = "img-bmp" , name = "get_image" , arguments = {})
769+
770+ mock_session .call_tool .assert_called_once_with ("get_image" , {}, None , meta = None )
771+ assert result ["status" ] == "success"
772+ assert len (result ["content" ]) == 1
773+ assert "json" in result ["content" ][0 ]
774+ assert result ["content" ][0 ]["json" ]["mimeType" ] == "image/bmp"
775+ assert result ["content" ][0 ]["json" ]["data" ] == payload
776+
777+
778+ def test_call_tool_sync_embedded_blob_decode_failure_falls_back_to_json (mock_transport , mock_session ):
779+ """EmbeddedResource.resource with an undecodable blob should fall back to json."""
780+ embedded_resource = {
781+ "type" : "resource" ,
782+ "resource" : {
783+ "uri" : "mcp://resource/bad-blob" ,
784+ "blob" : "!!!not-valid-base64!!!" ,
785+ "mimeType" : "image/png" ,
786+ },
787+ }
788+ mock_session .call_tool .return_value = MCPCallToolResult (isError = False , content = [embedded_resource ])
789+
790+ with MCPClient (mock_transport ["transport_callable" ]) as client :
791+ result = client .call_tool_sync (tool_use_id = "er-bad" , name = "get_file_contents" , arguments = {})
792+
793+ mock_session .call_tool .assert_called_once_with ("get_file_contents" , {}, None , meta = None )
794+ assert result ["status" ] == "success"
795+ assert len (result ["content" ]) == 1
796+ assert "json" in result ["content" ][0 ]
751797
752798
753799def test_call_tool_sync_embedded_multiple_textual_mimes (mock_transport , mock_session ):
0 commit comments