diff --git a/source/RobotAPI/applications/AronCodeGenerator/main.cpp b/source/RobotAPI/applications/AronCodeGenerator/main.cpp
index 5da09c7a9a41abf9fca00adff864567125983938..dbe232179fa40b7b8c24a8957730ca1a7113995d 100644
--- a/source/RobotAPI/applications/AronCodeGenerator/main.cpp
+++ b/source/RobotAPI/applications/AronCodeGenerator/main.cpp
@@ -63,7 +63,8 @@ int main(int argc, char* argv[])
 
         options.add_options("IO")
         ("i,input", "XML file name", cxxopts::value<std::string>()->default_value(input_default))
-        ("o,output", "The output path", cxxopts::value<std::string>()->default_value(output_default));
+        ("o,output", "The output path", cxxopts::value<std::string>()->default_value(output_default))
+        ("I,include", "include path", cxxopts::value<std::vector<std::string>>());
 
         options.add_options("Generation")
         ("f,force", "Enforce the generation", cxxopts::value<bool>()->default_value("false"));
@@ -108,6 +109,17 @@ int main(int argc, char* argv[])
         std::filesystem::path input_file(filename);
         std::filesystem::path output_folder(output);
 
+        std::vector<std::filesystem::path> includePaths;
+
+        if(result.count("I") > 0)
+        {
+            for(const auto& path: result["I"].as<std::vector<std::string>>())
+            {
+                includePaths.emplace_back(path);
+            }
+        }
+
+
         if (!std::filesystem::exists(input_file) || !std::filesystem::is_regular_file(input_file))
         {
             std::cerr << "The input file does not exist or is not a regular file." << std::endl;
@@ -132,7 +144,7 @@ int main(int argc, char* argv[])
         }
 
         typereader::xml::Reader reader;
-        reader.parseFile(input_file);
+        reader.parseFile(input_file, includePaths);
         if (verbose)
         {
             std::cout << "Parsing the XML file... done!" << std::endl;
diff --git a/source/RobotAPI/libraries/aron/core/typereader/Reader.h b/source/RobotAPI/libraries/aron/core/typereader/Reader.h
index c5e7b72347c0fe22541649c61305c3aff0962eed..d09c5967d34b70ee0d68ef7c72d233ca30c187e9 100644
--- a/source/RobotAPI/libraries/aron/core/typereader/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/typereader/Reader.h
@@ -47,10 +47,10 @@ namespace armarx::aron::typereader
         Reader() = default;
 
         /// parse a filename
-        virtual void parseFile(const std::string& filename) = 0;
+        virtual void parseFile(const std::string& filename, const std::vector<std::filesystem::path>& includePaths) = 0;
 
         /// path a file given by std::filesystem
-        virtual void parseFile(const std::filesystem::path& file) = 0;
+        virtual void parseFile(const std::filesystem::path& file, const std::vector<std::filesystem::path>& includePaths) = 0;
 
         std::vector<std::string> getCodeIncludes() const
         {
diff --git a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp
index c12e495c0c64693ab78e6af7ae7b84561b25d83e..a150fa341e4b427476e2ee17389bdade64c138dc 100644
--- a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp
+++ b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp
@@ -26,6 +26,7 @@
 
 // Header
 #include "Reader.h"
+#include <sstream>
 
 // ArmarX
 #include <ArmarXCore/core/rapidxml/wrapper/RapidXmlReader.h>
@@ -42,8 +43,20 @@ namespace armarx::aron::typereader::xml
     namespace
     {
         /// Resolve a relative Package path. This may be removed in a newer version of aron
-        std::optional<fs::path> resolveRelativePackagePath(const fs::path& path)
+        std::optional<fs::path> resolveRelativePackagePath(const fs::path& path, const std::vector<fs::path>& includePaths)
         {
+            // new behavior: using provided include paths
+            for (const auto& includePath : includePaths)
+            {
+                fs::path absPath = includePath / path;
+                if (fs::is_regular_file(absPath))
+                {
+                    // path is valid
+                    return absPath;
+                }
+            }
+
+            // legacy behavior: using cmake package finder paths
             const std::string package = *path.begin();
             armarx::CMakePackageFinder finder(package);
             if (finder.packageFound())
@@ -59,14 +72,12 @@ namespace armarx::aron::typereader::xml
                 }
                 return std::nullopt;
             }
-            else
-            {
-                return std::nullopt;
-            }
+
+            return std::nullopt;
         }
     }
 
-    void Reader::parseFile(const std::string& _filename)
+    void Reader::parseFile(const std::string& _filename, const std::vector<std::filesystem::path>& includePaths)
     {
         std::string filename = _filename;
         // Handle C++ style includes like "<path/to/file>".
@@ -74,19 +85,19 @@ namespace armarx::aron::typereader::xml
         {
             filename = filename.substr(1, filename.size() - 2);
         }
-        parseFile(std::filesystem::path(filename));
+        parseFile(std::filesystem::path(filename), includePaths);
     }
 
-    void Reader::parseFile(const std::filesystem::path& _file)
+    void Reader::parseFile(const std::filesystem::path& _file, const std::vector<std::filesystem::path>& includePaths)
     {
         fs::path file = _file;
 
         RapidXmlReaderPtr reader = RapidXmlReader::FromFile(file.string());
-        parse(reader, _file);
+        parse(reader, _file, includePaths);
     }
 
     // private method reading nodes
-    void Reader::parse(const RapidXmlReaderPtr& reader, const std::filesystem::path& filePath)
+    void Reader::parse(const RapidXmlReaderPtr& reader, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
     {
         RapidXmlReaderNode root = reader->getRoot();
 
@@ -104,7 +115,7 @@ namespace armarx::aron::typereader::xml
         {
             for (const auto& include : (*code_includes).nodes())
             {
-                this->codeIncludes.push_back(readCodeInclude(include, filePath));
+                this->codeIncludes.push_back(readCodeInclude(include, filePath, includePaths));
             }
         }
 
@@ -113,7 +124,7 @@ namespace armarx::aron::typereader::xml
         {
             for (const auto& aronInclude : (*aron_includes).nodes())
             {
-                this->aronIncludes.push_back(readAronInclude(aronInclude, filePath));
+                this->aronIncludes.push_back(readAronInclude(aronInclude, filePath, includePaths));
             }
         }
 
@@ -144,7 +155,7 @@ namespace armarx::aron::typereader::xml
         }
     }
 
-    std::string Reader::readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath)
+    std::string Reader::readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
     {
         util::EnforceTagName(node, constantes::INCLUDE_TAG);
         util::EnforceAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
@@ -152,7 +163,7 @@ namespace armarx::aron::typereader::xml
         return include;
     }
 
-    std::string Reader::readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath)
+    std::string Reader::readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
     {
         util::EnforceTagName(node, constantes::INCLUDE_TAG);
         std::string specifiedPath = util::GetAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
@@ -166,7 +177,8 @@ namespace armarx::aron::typereader::xml
 
         if (!xmlincludepath.empty() && xmlincludepath.is_relative())
         {
-            if (std::optional<fs::path> resolvedPackagePath = resolveRelativePackagePath(xmlincludepath); resolvedPackagePath.has_value())
+            // ARMARX_INFO << "Checking file " << xmlincludepath;
+            if (std::optional<fs::path> resolvedPackagePath = resolveRelativePackagePath(xmlincludepath, includePaths); resolvedPackagePath.has_value())
             {
                 // check if relative path belongs to a package
                 resolved_absolute_path = resolvedPackagePath.value();
@@ -181,7 +193,13 @@ namespace armarx::aron::typereader::xml
 
                 if (!fs::is_regular_file(resolved_absolute_path))
                 {
-                    throw error::AronException(__PRETTY_FUNCTION__, "Could not find an aron XML file. Last path tried was: " + resolved_absolute_path.string());
+                    std::stringstream ss;
+                    for(const auto& includePath: includePaths)
+                    {
+                        ss << includePath << ", ";
+                    }
+
+                    throw error::AronException(__PRETTY_FUNCTION__, "Could not find an aron XML file `" + xmlincludepath.string() + "`. Search paths are: " + ss.str());
                 }
             }
         }
@@ -189,7 +207,7 @@ namespace armarx::aron::typereader::xml
 
         // parse parent xml file and add objects to alreday known
         Reader anotherReader;
-        anotherReader.parseFile(resolved_absolute_path);
+        anotherReader.parseFile(resolved_absolute_path, includePaths);
         for (const auto& previouslyKnown : anotherReader.factory.allPreviouslyKnownPublicTypes)
         {
             factory.allPreviouslyKnownPublicTypes.push_back(previouslyKnown);
@@ -224,5 +242,3 @@ namespace armarx::aron::typereader::xml
         return type::IntEnum::DynamicCastAndCheck(factory.create(node, Path()));
     }
 }
-
-
diff --git a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.h b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.h
index cd048d4dca481083639bfa282072570f61ac8d5d..91647c64a238cbd237656e5ac454670e82873e19 100644
--- a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.h
@@ -50,14 +50,14 @@ namespace armarx::aron::typereader::xml
     public:
         Reader() = default;
 
-        void parseFile(const std::string&) override;
-        void parseFile(const std::filesystem::path&) override;
+        void parseFile(const std::string& filename, const std::vector<std::filesystem::path>& includePaths) override;
+        void parseFile(const std::filesystem::path& file, const std::vector<std::filesystem::path>& includePaths) override;
 
     private:
-        void parse(const RapidXmlReaderPtr& node, const std::filesystem::path& filePath);
+        void parse(const RapidXmlReaderPtr& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
 
-        std::string readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath);
-        std::string readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath);
+        std::string readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
+        std::string readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
 
         type::ObjectPtr readGenerateObject(const RapidXmlReaderNode& node);
         type::IntEnumPtr readGenerateIntEnum(const RapidXmlReaderNode& node);