diff --git a/examples/test_csv.json b/examples/test_csv.json
index 721ceee308bde6478d91c6b8e59419a7dbc667ab..0fe50484a4c12813bcb882f6ea2d865aa9aac6bb 100644
--- a/examples/test_csv.json
+++ b/examples/test_csv.json
@@ -1,7 +1,9 @@
 {
   "multi_criteria_optimizer": {
     "name": "dakota",
-    "model_data": {}
+    "model_data": {
+      "value_types": ["DUMMY"]
+    }
   },
   "data_sources": [
     {
diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index 54932bea10456e089627b8b339215ab492b352f2..b9e001e3a7e9f17bdc3328dfba785fb103b57bdb 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -41,68 +41,63 @@ class CoreMCODriver(Plugin):
     @on_trait_change("application:started")
     def application_started(self):
         workflow = self.application.workflow
-        if self.application.evaluate:
-            ds_results = []
-            for requested_ds in workflow.data_sources:
-                ds_bundle = self._find_data_source_bundle_by_name(
-                    requested_ds.name)
-                if ds_bundle:
-                    ds_model = ds_bundle.create_model(requested_ds.model_data)
-                    data_source = ds_bundle.create_data_source(
-                        self.application, ds_model)
-                    ds_results.append(data_source.run())
-                else:
-                    raise Exception("Requested data source {} but don't know "
-                                    "to find it.".format(requested_ds.name))
-
-            kpi_results = []
-            for requested_kpic in workflow.kpi_calculators:
-                kpic_bundle = self._find_kpi_calculator_bundle_by_name(
-                    requested_kpic.name)
-                if kpic_bundle:
-                    ds_model = kpic_bundle.create_model(
-                        requested_kpic.model_data)
-                    kpi_calculator = kpic_bundle.create_data_source(
-                        self.application, ds_model)
-                    kpi_results.append(kpi_calculator.run(ds_results))
-                else:
-                    raise Exception(
-                        "Requested kpi calculator {} but don't know "
-                        "to find it.".format(requested_kpic.name))
-
-                print(
-                    kpi_results[0].value_types,
-                    kpi_results[0].values
-                )
-
-        else:
-            mco_data = workflow.multi_criteria_optimizer
-            mco_bundle = self._find_mco_bundle_by_name(mco_data.name)
-            if mco_bundle:
-                mco_model = mco_bundle.create_model(mco_data.model_data)
-                mco = mco_bundle.create_optimizer(self.application, mco_model)
-                mco.run()
-            else:
-                raise Exception("Requested MCO {} but it's not available"
-                                "to compute it.".format(mco_data.name))
-
-    def _find_data_source_bundle_by_name(self, name):
+
+        mco_data = workflow.multi_criteria_optimizer
+        mco_bundle = self._mco_bundle_by_name(mco_data.name)
+        mco_model = mco_bundle.create_model(mco_data.model_data)
+        mco = mco_bundle.create_optimizer(self.application, mco_model)
+        mco_communicator = mco_bundle.create_communicator(
+            self.application,
+            mco_model)
+
+        if not self.application.evaluate:
+            mco.run()
+            return
+
+        parameters = mco_communicator.receive_from_mco()
+
+        ds_results = []
+        for requested_ds in workflow.data_sources:
+            ds_bundle = self._data_source_bundle_by_name(
+                requested_ds.name)
+            ds_model = ds_bundle.create_model(requested_ds.model_data)
+            data_source = ds_bundle.create_data_source(
+                self.application, ds_model)
+            ds_results.append(data_source.run(parameters))
+
+        kpi_results = []
+        for requested_kpic in workflow.kpi_calculators:
+            kpic_bundle = self._kpi_calculator_bundle_by_name(
+                requested_kpic.name)
+            ds_model = kpic_bundle.create_model(
+                requested_kpic.model_data)
+            kpi_calculator = kpic_bundle.create_data_source(
+                self.application, ds_model)
+            kpi_results.append(kpi_calculator.run(ds_results))
+
+        mco_communicator.send_to_mco(kpi_results)
+
+    def _data_source_bundle_by_name(self, name):
         for ds in self.data_source_bundles:
             if ds.name == name:
                 return ds
 
-        return None
+        raise Exception("Requested data source {} but don't know "
+                        "to find it.".format(name))
 
-    def _find_kpi_calculator_bundle_by_name(self, name):
+    def _kpi_calculator_bundle_by_name(self, name):
         for kpic in self.kpi_calculator_bundles:
             if kpic.name == name:
                 return kpic
 
-        return None
+        raise Exception(
+            "Requested kpi calculator {} but don't know "
+            "to find it.".format(name))
 
-    def _find_mco_bundle_by_name(self, name):
+    def _mco_bundle_by_name(self, name):
         for mco in self.mco_bundles:
             if mco.name == name:
                 return mco
 
-        return None
+        raise Exception("Requested MCO {} but it's not available"
+                        "to compute it.".format(mco_data.name))
diff --git a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py
index 8cfb74e216012d83c3cb1a5bf819617f0ae4ae6b..7208153c407f679ab45978fa594415ce3cb7d67b 100644
--- a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py
+++ b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py
@@ -5,7 +5,7 @@ from force_bdss.data_sources.data_source_result import DataSourceResult
 
 
 class CSVExtractorDataSource(BaseDataSource):
-    def run(self):
+    def run(self, parameters):
         with open(self.model.filename) as csvfile:
             reader = csv.reader(csvfile)
             for rowindex, row in enumerate(reader):
@@ -17,7 +17,8 @@ class CSVExtractorDataSource(BaseDataSource):
                         originator=self,
                         value_types = [self.model.cuba_type],
                         values=numpy.array(
-                            float(row[self.model.column])).reshape(1,1)
+                            parameters.values[0]+float(
+                                row[self.model.column])).reshape(1,1)
                     )
 
                 return None
diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py b/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py
index 12c34ab2e3502eb1edbbf0ef9952551da93b0db8..effed5735912edbfbd331e04a69aaf1dfce4b59e 100644
--- a/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py
+++ b/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py
@@ -1,6 +1,8 @@
 from traits.has_traits import HasStrictTraits, provides
 from traits.trait_types import String
 
+from force_bdss.core_plugins.test_mco.dakota.dakota_communicator import \
+    DakotaCommunicator
 from force_bdss.mco.i_multi_criteria_optimizer_bundle import (
     IMultiCriteriaOptimizerBundle)
 
@@ -17,3 +19,6 @@ class DakotaBundle(HasStrictTraits):
 
     def create_optimizer(self, application, model):
         return DakotaOptimizer(self, application, model)
+
+    def create_communicator(self, application, model):
+        return DakotaCommunicator(self, application, model)
diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py b/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae9677fdf72b409ef79956c3852163da4ba9d35c
--- /dev/null
+++ b/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py
@@ -0,0 +1,27 @@
+import sys
+import numpy
+
+from force_bdss.data_sources.data_source_parameters import DataSourceParameters
+from force_bdss.mco.base_mco_communicator import BaseMCOCommunicator
+
+
+class DakotaCommunicator(BaseMCOCommunicator):
+    def receive_from_mco(self):
+        data = sys.stdin.read()
+        values = list(map(float, data.split()))
+        value_types = self.model.value_types
+        if len(values) != len(value_types):
+            raise ValueError("Length of provided data differs from the number "
+                             "of expected types. {} {}".format(values,
+                                                               value_types))
+
+        return DataSourceParameters(
+            value_types=value_types,
+            values=numpy.array(values)
+        )
+
+    def send_to_mco(self, kpi_results):
+        data = " ".join(
+            [" ".join(list(map(str, r.values.tolist()))) for r in kpi_results]
+        )
+        sys.stdout.write(data)
diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_model.py b/force_bdss/core_plugins/test_mco/dakota/dakota_model.py
index ed6ff342dfdd8c2ee8742ba32f86808cb8f82582..fe7edcdc6cb3411945de29cdec4806e5cecce88f 100644
--- a/force_bdss/core_plugins/test_mco/dakota/dakota_model.py
+++ b/force_bdss/core_plugins/test_mco/dakota/dakota_model.py
@@ -1,7 +1,9 @@
-from traits.api import HasStrictTraits
+from traits.api import HasStrictTraits, List, String
 
 
 class DakotaModel(HasStrictTraits):
+    value_types = List(String)
+
     @classmethod
     def from_json(cls, model_data):
-        return cls()
+        return cls(value_types=model_data["value_types"])
diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py b/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py
index 0f8f064cc985e2afdb6fc99765f42596ae49cece..edd177d6e863c41a4e6b378926ceff92a5b3c15a 100644
--- a/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py
+++ b/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py
@@ -10,5 +10,13 @@ from force_bdss.mco.base_multi_criteria_optimizer import (
 class DakotaOptimizer(BaseMultiCriteriaOptimizer):
     def run(self):
         print("Running dakota optimizer")
-        subprocess.check_call([sys.argv[0], "--evaluate",
-                               self.application.workflow_filepath])
+        for initial_value in range(10):
+            ps = subprocess.Popen(
+                [sys.argv[0],
+                 "--evaluate",
+                 self.application.workflow_filepath],
+                stdout=subprocess.PIPE,
+                stdin=subprocess.PIPE)
+
+            out = ps.communicate("{}".format(initial_value).encode("utf-8"))
+            print("{}: {}".format(initial_value, out[0].decode("utf-8")))
diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py
index 469ed8b902cc9d237139bf6b53ef6e2a952a20e8..e8eec36d78660d9aab8eb24f2e140392d807a05e 100644
--- a/force_bdss/data_sources/base_data_source.py
+++ b/force_bdss/data_sources/base_data_source.py
@@ -13,7 +13,7 @@ class BaseDataSource(six.with_metaclass(abc.ABCMeta)):
         return self.bundle.name
 
     @abc.abstractmethod
-    def run(self):
+    def run(self, parameters):
         """Executes the data source evaluation/fetching and returns
         the list of results as a DataSourceResult instance."""
         pass
diff --git a/force_bdss/data_sources/data_source_parameters.py b/force_bdss/data_sources/data_source_parameters.py
new file mode 100644
index 0000000000000000000000000000000000000000..c45915dd1f056873e96e9e957753a90409c3d215
--- /dev/null
+++ b/force_bdss/data_sources/data_source_parameters.py
@@ -0,0 +1,6 @@
+from traits.api import HasStrictTraits, Array, List, String
+
+
+class DataSourceParameters(HasStrictTraits):
+    value_types = List(String)
+    values = Array(shape=(None,))
diff --git a/force_bdss/mco/base_mco_communicator.py b/force_bdss/mco/base_mco_communicator.py
new file mode 100644
index 0000000000000000000000000000000000000000..308903166cdebdbf8dcee705ff4089fb626e3639
--- /dev/null
+++ b/force_bdss/mco/base_mco_communicator.py
@@ -0,0 +1,17 @@
+import abc
+import six
+
+
+class BaseMCOCommunicator(six.with_metaclass(abc.ABCMeta)):
+    def __init__(self, bundle, application, model):
+        self.bundle = bundle
+        self.application = application
+        self.model = model
+
+    @abc.abstractmethod
+    def receive_from_mco(self):
+        pass
+
+    @abc.abstractmethod
+    def send_to_mco(self):
+        pass
diff --git a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py
index 33c9a37c78a932045132609ef4f3a455b706ba22..f84cca5379b0bacb7ca11365ac84777307015cdb 100644
--- a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py
+++ b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py
@@ -9,3 +9,6 @@ class IMultiCriteriaOptimizerBundle(Interface):
 
     def create_model(self, model_data):
         pass
+
+    def create_communicator(self, model_data):
+        pass