diff --git a/force_bdss/core/slot.py b/force_bdss/core/slot.py
new file mode 100644
index 0000000000000000000000000000000000000000..22182759c6be5ab0a05833916b7e03fbfdcbb09b
--- /dev/null
+++ b/force_bdss/core/slot.py
@@ -0,0 +1,11 @@
+from traits.api import HasStrictTraits, String
+
+
+class Slot(HasStrictTraits):
+    """Describes an input or output slot in the DataSource or
+    KPICalculator"""
+    #: A textual description of the slot
+    description = String("No description")
+
+    #: The CUBA key of the slot
+    type = String()
diff --git a/force_bdss/core/tests/test_slot.py b/force_bdss/core/tests/test_slot.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6c687e596eb92e7b6a8f256a720ff9528a95fa4
--- /dev/null
+++ b/force_bdss/core/tests/test_slot.py
@@ -0,0 +1,10 @@
+import unittest
+
+from force_bdss.core.slot import Slot
+
+
+class TestSlot(unittest.TestCase):
+    def test_initialization(self):
+        slot = Slot()
+        self.assertEqual(slot.type, "")
+        self.assertEqual(slot.description, "No description")
diff --git a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py
index 471f3ac6c18592ed248d6a18d12559bdc6359340..36f729720f8933fe6121d1c820bcb6f09ea662f0 100644
--- a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py
+++ b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py
@@ -1,5 +1,6 @@
 import csv
 from force_bdss.api import BaseDataSource, DataValue
+from force_bdss.core.slot import Slot
 
 
 class CSVExtractorDataSource(BaseDataSource):
@@ -20,3 +21,11 @@ class CSVExtractorDataSource(BaseDataSource):
                     break
 
             raise IndexError("Could not find specified data.")
+
+    def slots(self, model):
+        return (
+            (),
+            (
+                Slot(type=model.cuba_type),
+            )
+        )
diff --git a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py
index 03c36de2f42e17926d2069a6b7723e46b986980e..ac4dc61f73b6c3d9f8609187695242e852492172 100644
--- a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py
+++ b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py
@@ -4,3 +4,6 @@ from force_bdss.api import BaseDataSource
 class DummyDataSource(BaseDataSource):
     def run(self, model, parameters):
         return parameters
+
+    def slots(self, model):
+        return (), ()
diff --git a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py
index bd104731babee708112797eebe991a1ca732504e..3e035cb77ed03c4ccd01960978eca8222f7a26c8 100644
--- a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py
+++ b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py
@@ -4,3 +4,6 @@ from force_bdss.api import BaseKPICalculator
 class DummyKPICalculator(BaseKPICalculator):
     def run(self, model, data_source_results):
         return data_source_results
+
+    def slots(self, model):
+        return (), ()
diff --git a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py
index 94128b30519bf6bcac5fc63e0f418cd758ea7f80..ff4b7ce8da3161864c33a486f7b1413bd14da599 100644
--- a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py
+++ b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py
@@ -1,4 +1,5 @@
 from force_bdss.api import BaseKPICalculator, DataValue
+from force_bdss.core.slot import Slot
 
 
 class KPIAdderCalculator(BaseKPICalculator):
@@ -16,3 +17,13 @@ class KPIAdderCalculator(BaseKPICalculator):
                 type=model.cuba_type_out,
                 value=sum
             )]
+
+    def slots(self, model):
+        return (
+            (
+                Slot(type=model.cuba_type_in),
+            ),
+            (
+                Slot(type=model.cuba_type_out),
+            )
+        )
diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py
index e0283b5da75b9d2fb7a42f69049c54b482d4f00d..be9fb39f4f338fb5cca32664ac3a4970596d0f4b 100644
--- a/force_bdss/data_sources/base_data_source.py
+++ b/force_bdss/data_sources/base_data_source.py
@@ -55,8 +55,14 @@ class BaseDataSource(ABCHasStrictTraits):
 
         Returns
         -------
-        list[tuple, tuple]
-            A list containing two tuples, the first element is the input slots,
-            the second element is the output slots. Each slot must be an
-            instance of the Slot class.
+        (input_slots, output_slots): tuple[tuple, tuple]
+            A tuple containing two tuples.
+            The first element is the input slots, the second element is
+            the output slots. Each slot must be an instance of the Slot class.
+            It is possible for each of the two inside tuples to be empty.
+            The case of an empty input slot is common: the DataSource does
+            not need any information from the MCO to operate.
+            The case of an empty output slot is uncommon, but supported:
+            the DataSource does not produce any output and is therefore
+            useless.
         """
diff --git a/force_bdss/data_sources/tests/test_base_data_source.py b/force_bdss/data_sources/tests/test_base_data_source.py
index 810b5f63805914b3b7c872d983eaaae022bbc471..a4de04182cb54cfd711cbf18ba7517ab2149151e 100644
--- a/force_bdss/data_sources/tests/test_base_data_source.py
+++ b/force_bdss/data_sources/tests/test_base_data_source.py
@@ -13,6 +13,9 @@ class DummyDataSource(BaseDataSource):
     def run(self, *args, **kwargs):
         pass
 
+    def slots(self, model):
+        return (), ()
+
 
 class TestBaseDataSource(unittest.TestCase):
     def test_initialization(self):
diff --git a/force_bdss/kpi/base_kpi_calculator.py b/force_bdss/kpi/base_kpi_calculator.py
index 1bb1bf4867755639e5edf999ef9748a0e0cd8495..b757dd403a9460d53e04d3aa7dd13ac833c5d2a2 100644
--- a/force_bdss/kpi/base_kpi_calculator.py
+++ b/force_bdss/kpi/base_kpi_calculator.py
@@ -38,3 +38,32 @@ class BaseKPICalculator(ABCHasStrictTraits):
         List[DataValue]:
             The result of this KPI evaluation, as a list of DataValues.
         """
+
+    @abc.abstractmethod
+    def slots(self, model):
+        """Returns the input (and output) slots of the KPI Calculator.
+        Slots are the entities that are needed (and produced) by this
+        KPI Calculator.
+
+        The slots may depend on the configuration options, and thus the model.
+        This allows, for example, to change the slots depending if an option
+        is enabled or not.
+
+        Parameters
+        ----------
+        model: BaseKPICalculatorModel
+            The model of the KPICalculator, instantiated through create_model()
+
+        Returns
+        -------
+        (input_slots, output_slots): tuple[tuple, tuple]
+            A tuple containing two tuples.
+            The first element is the input slots, the second element is
+            the output slots. Each slot must be an instance of the Slot class.
+            It is possible for each of the two inside tuples to be empty.
+            The case of an empty input slot is common: the KPICalculator does
+            not need any information from the MCO to operate.
+            The case of an empty output slot is uncommon, but supported:
+            the KPICalculator does not produce any output and is therefore
+            useless.
+        """
diff --git a/force_bdss/kpi/tests/test_base_kpi_calculator.py b/force_bdss/kpi/tests/test_base_kpi_calculator.py
index 548383573691a320db5ec29c4664a62037a9be53..334c1915535d576c9d444a4de0e60fef6f13706a 100644
--- a/force_bdss/kpi/tests/test_base_kpi_calculator.py
+++ b/force_bdss/kpi/tests/test_base_kpi_calculator.py
@@ -12,6 +12,9 @@ class DummyKPICalculator(BaseKPICalculator):
     def run(self, *args, **kwargs):
         pass
 
+    def slots(self, model):
+        return (), ()
+
 
 class TestBaseKPICalculator(unittest.TestCase):
     def test_initialization(self):
diff --git a/force_bdss/tests/test_core_evaluation_driver.py b/force_bdss/tests/test_core_evaluation_driver.py
index 3ce84809480eb25565fb014814feed26888313e8..fc79b484871b7e065956eccfe2a532a008c6db48 100644
--- a/force_bdss/tests/test_core_evaluation_driver.py
+++ b/force_bdss/tests/test_core_evaluation_driver.py
@@ -80,6 +80,9 @@ class NullKPICalculator(BaseKPICalculator):
     def run(self, model, data_source_results):
         return []
 
+    def slots(self, model):
+        return (), ()
+
 
 class NullKPICalculatorBundle(BaseKPICalculatorBundle):
     def create_model(self, model_data=None):
@@ -97,6 +100,9 @@ class NullDataSource(BaseDataSource):
     def run(self, model, parameters):
         return []
 
+    def slots(self, model):
+        return (), ()
+
 
 class NullDataSourceBundle(BaseDataSourceBundle):
     def create_model(self, model_data=None):