diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py
index 00da3a39be927b3e482b95310a9b7fe198685e43..9733fbb5edd8ce81988abc9b70f2e51c519615d6 100644
--- a/nomad/metainfo/metainfo.py
+++ b/nomad/metainfo/metainfo.py
@@ -401,7 +401,7 @@ class Reference(DataType):
 class QuantityReference(Reference):
     ''' Datatype used for reference quantities that reference other quantities. '''
 
-    def __init__(self, quantity_def: Union['Quantity']):
+    def __init__(self, quantity_def: 'Quantity'):
         super().__init__(cast(Section, quantity_def.m_parent))
         self.target_quantity_def = quantity_def
 
@@ -2063,6 +2063,10 @@ class Definition(MSection):
             sections, which organize the data (e.g. quantity values) and not the definitions
             of data (e.g. quantities definitions). See :ref:`metainfo-categories` for more
             details.
+
+        more: A dictionary that contains additional definition properties that are not
+            part of the metainfo. Those can be passed as additional kwargs to definition
+            constructors. The values must be JSON serializable.
     '''
 
     name: 'Quantity' = _placeholder_quantity
@@ -2071,6 +2075,27 @@ class Definition(MSection):
     categories: 'Quantity' = _placeholder_quantity
     deprecated: 'Quantity' = _placeholder_quantity
     aliases: 'Quantity' = _placeholder_quantity
+    more: 'Quantity' = _placeholder_quantity
+
+    def __init__(self, *args, **kwargs):
+        if is_bootstrapping:
+            super().__init__(*args, **kwargs)
+            return
+
+        # We add all kwargs that are not meta props, annotations, or metainfo properties
+        # to the more property.
+        more = {}
+        new_kwargs = {}
+        for key, value in kwargs.items():
+            if key.startswith('m_') or key.startswith('a_') or key in m_package.all_properties:
+                new_kwargs[key] = value
+            else:
+                more[key] = value
+
+        if len(more) > 0:
+            new_kwargs['more'] = more
+
+        super().__init__(*args, **new_kwargs)
 
     def __init_metainfo__(self):
         '''
@@ -2093,6 +2118,12 @@ class Definition(MSection):
         for content in self.m_all_contents(depth_first=True):
             content.__init_metainfo__()
 
+    def __getattr__(self, name):
+        if name in self.more:
+            return self.more[name]
+
+        raise super().__getattr__(name)
+
     def qualified_name(self):
         names = []
         current = self
@@ -2768,12 +2799,17 @@ class Package(Definition):
 
         all_definitions: A helper attribute that provides all section definitions
             by name.
+
+        all_properties: A helper attribute that provides all properties in all sections
+            of this package by name. The values are lists of properties as property names
+            do not necesseraly need to be unique for different containing sections.
     '''
 
     section_definitions: 'SubSection' = None
     category_definitions: 'SubSection' = None
 
     all_definitions: 'Quantity' = _placeholder_quantity
+    all_properties: 'Quantity' = _placeholder_quantity
     dependencies: 'Quantity' = _placeholder_quantity
 
     registry: Dict[str, 'Package'] = {}
@@ -2893,6 +2929,7 @@ Definition.categories = Quantity(
     type=Reference(Category.m_def), shape=['0..*'], default=[], name='categories')
 Definition.deprecated = Quantity(type=str, name='deprecated')
 Definition.aliases = Quantity(type=str, shape=['0..*'], default=[], name='aliases')
+Definition.more = Quantity(type=JSON, name='more', default={})
 
 Section.quantities = SubSection(
     sub_section=Quantity.m_def, name='quantities', repeats=True)
@@ -3023,6 +3060,17 @@ def all_definitions(self):
     return all_definitions
 
 
+@derived(cached=True)
+def package_all_properties(self):
+    all_properties: Dict[str, List[Property]] = dict()
+    for section_def in self.section_definitions:
+        for sub_section_def in [Section.quantities, Section.sub_sections]:
+            for property in section_def.m_get_sub_sections(sub_section_def):
+                properties = all_properties.setdefault(property.name, [])
+                properties.append(property)
+    return all_properties
+
+
 @derived(cached=True)
 def dependencies(self):
     '''
@@ -3060,6 +3108,7 @@ def dependencies(self):
 
 
 Package.all_definitions = all_definitions
+Package.all_properties = package_all_properties
 Package.dependencies = dependencies
 
 is_bootstrapping = False
@@ -3107,7 +3156,7 @@ class Environment(MSection):
 
         return [
             definition
-            for definition in self.all_definitions_by_name.get(name, [])
+            for definition in self.all_definitions_by_name.get(name, [])  # pylint: disable=no-member
             if isinstance(definition, section_cls)
             if not (isinstance(definition, Section) and definition.extends_base_section)
             if filter is None or filter(definition)]
diff --git a/tests/metainfo/test_metainfo.py b/tests/metainfo/test_metainfo.py
index 9f5430d62e025f2db30becea6af30a053a5477cf..98b0e71238973600f2f21977fef7944dd406e1db 100644
--- a/tests/metainfo/test_metainfo.py
+++ b/tests/metainfo/test_metainfo.py
@@ -313,6 +313,28 @@ class TestM2:
         assert len(TestSection.list_test_quantity.m_get_annotations(TestDefinitionAnnotation)) == 2
         assert TestSection.test_sub_section.a_test is not None
 
+    def test_more_property(self):
+        class TestSection(MSection):
+            m_def = Section(this_does_not_exist_in_metainfo='value')
+            test_quantity = Quantity(type=str, also_no_metainfo_quantity=1, one_more=False)
+            another_test_quantity = Quantity(type=str)
+
+        assert TestSection.m_def.more['this_does_not_exist_in_metainfo'] == 'value'
+        assert TestSection.test_quantity.more['also_no_metainfo_quantity'] == 1
+        assert not TestSection.test_quantity.more['one_more']
+        assert len(TestSection.another_test_quantity.more) == 0
+
+        assert TestSection.m_def.this_does_not_exist_in_metainfo == 'value'
+        assert TestSection.test_quantity.also_no_metainfo_quantity == 1
+        assert not TestSection.test_quantity.one_more
+        with pytest.raises(AttributeError):
+            assert TestSection.not_even_in_more is None
+
+        serialized = TestSection.m_def.m_to_dict()
+        assert 'more' in serialized
+        assert 'this_does_not_exist_in_metainfo' in serialized['more']
+        assert 'this_does_not_exist_in_metainfo' not in serialized
+
 
 class TestM1:
     ''' Test for meta-info instances. '''
@@ -509,7 +531,7 @@ class TestM1:
             def derived(self):
                 return self.value + self.list[0]
 
-        assert TestSection.derived.cached
+        assert TestSection.derived.cached  # pylint: disable=no-member
         test_section = TestSection(value='test', list=['1'])
         assert test_section.derived == 'test1'
         test_section.value = '2'