diff --git a/geomagio/Controller.py b/geomagio/Controller.py
index 96ebb28c2f5c76274d90418b7a9892c76ab52ed5..0985597c37f0e3ff6912b03eaceb009a6ad0ab96 100644
--- a/geomagio/Controller.py
+++ b/geomagio/Controller.py
@@ -503,7 +503,7 @@ def get_input_factory(args):
     input_type = args.input
     # stream/url arguments
     if args.input_file is not None:
-        if input_type in ["netcdf", "miniseed"]:
+        if input_type in ["netcdf", "miniseed", "imagcdf"]:
             input_stream = open(args.input_file, "rb")
         else:
             input_stream = open(args.input_file, "r")
@@ -547,8 +547,6 @@ def get_input_factory(args):
             locationCode=args.locationcode,
             **input_factory_args,
         )
-    elif input_type == "imagcdf":
-        input_factory = ImagCDFFactory(**input_factory_args)
     else:
         # stream compatible factories
         if input_type == "iaga2002":
@@ -573,6 +571,8 @@ def get_input_factory(args):
             input_factory = xml.XMLFactory(**input_factory_args)
         elif input_type == "covjson":
             input_factory = covjson.CovJSONFactory(**input_factory_args)
+        elif input_type == "imagcdf":
+            input_factory = ImagCDFFactory(**input_factory_args)
         # wrap stream
         if input_stream is not None:
             input_factory = StreamTimeseriesFactory(
diff --git a/geomagio/ImagCDFFactory.py b/geomagio/ImagCDFFactory.py
index ea94790320d45247416ca1b4957fc66b522aec67..af603201de1773abdfcbe65836f290142e28d590 100644
--- a/geomagio/ImagCDFFactory.py
+++ b/geomagio/ImagCDFFactory.py
@@ -164,7 +164,7 @@ class ImagCDFFactory(TimeseriesFactory):
                     "Rec_Vary": True,
                     "Var_Type": "zVariable",
                     "Dim_Sizes": [],
-                    "Sparse": "no_sparse",
+                    "Sparse": "no_sparse",  # no_sparse because there should not be time gaps.
                     "Compress": 9,
                     "Pad": None,
                 }
@@ -424,6 +424,47 @@ class ImagCDFFactory(TimeseriesFactory):
         timeseries.sort()
         return timeseries
 
+    def parse_string(self, data: str, **kwargs):
+        """
+        Parse ImagCDF binary data into an ObsPy Stream.
+
+        This method writes the provided binary data to a temporary file,
+        reads the file using `cdflib`, and converts the data into an ObsPy
+        Stream.
+
+        Parameters
+        ----------
+        data : bytes
+            Binary data containing ImagCDF content.
+
+        Returns
+        -------
+        Stream
+            An ObsPy Stream object with the parsed geomagnetic time series data.
+
+        Raises
+        ------
+        TimeseriesFactoryException
+            If an error occurs while parsing the ImagCDF data.
+        """
+        # Create a temporary file to store the CDF data
+        with tempfile.NamedTemporaryFile(delete=False, suffix=".cdf") as tmp_file:
+            tmp_file_name = tmp_file.name
+            tmp_file.write(data)
+
+        try:
+            # Read the CDF from the temporary file
+            cdf = CDFReader(tmp_file_name)
+            stream = self._read_cdf(cdf)
+            # no cdf.close() method required
+        except Exception as e:
+            raise TimeseriesFactoryException(f"Error parsing ImagCDF data: {e}")
+        finally:
+            # Clean up the temporary file
+            os.remove(tmp_file_name)
+
+        return stream
+
     def _create_global_attributes(
         self, timeseries: Stream, channels: List[str]
     ) -> dict:
@@ -753,18 +794,12 @@ class ImagCDFFactory(TimeseriesFactory):
                 # If no DEPEND_0, skip this variable as we cannot map times
                 continue
 
-            # If we used a DataTimes fallback or similar, ensure we handle it case-insensitively
-            # and also confirm that time_vars keys are checked properly.
-            # The ImagCDF can have DataTimes, GeomagneticVectorTimes, etc.
-            # So try exact match first, if not found, attempt case-insensitive.
+            # The ImagCDF can have DataTimes, GeomagneticVectorTimes, GeomagneticScalarTimes, TemperatureNTimes (for N > 0), etc.
             matched_time_key = None
             for tkey in time_vars.keys():
                 if tkey == ts_name:
                     matched_time_key = tkey
                     break
-                if tkey.lower() == ts_name.lower():
-                    matched_time_key = tkey
-                    break
 
             if matched_time_key not in time_vars:
                 # If we cannot find the matching time variable, skip this variable