diff --git a/ai_eca.post_update.php b/ai_eca.post_update.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0d71f0c9acd24a0b8aa54fd75e134888ab04489
--- /dev/null
+++ b/ai_eca.post_update.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for AI ECA module.
+ */
+
+/**
+ * Ensure that cache is cleared.
+ */
+function ai_eca_post_update_prepare_mcp() {
+  // Empty update to cause a cache flush to rebuilt the service container.
+}
diff --git a/ai_integration_eca.info.yml b/ai_integration_eca.info.yml
index 0855494141616fe9bb8575c1f8e2def3f4b2d088..bb32b45704af228fa6daa0f922972bda93d1d454 100644
--- a/ai_integration_eca.info.yml
+++ b/ai_integration_eca.info.yml
@@ -9,3 +9,5 @@ dependencies:
   - ai:ai
   - drupal:file
   - eca:eca
+  - schemata:schemata_json_schema
+  - token:token
diff --git a/ai_integration_eca.services.yml b/ai_integration_eca.services.yml
index a7502590f4380fcd7a8ed418e0db68dbc1129c58..626d640fc610af89895b43ba201e03548173c9fb 100644
--- a/ai_integration_eca.services.yml
+++ b/ai_integration_eca.services.yml
@@ -4,6 +4,37 @@ services:
     arguments:
       - 'ai_integration_eca'
 
-  ai_integration_eca.provider_validator:
-    class: Drupal\ai_integration_eca\Service\AiProviderValidator
+  ai_integration_eca.services.provider_validator:
+    class: Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidator
     arguments: ['@validation.basic_recursive_validator_factory']
+
+  ai_integration_eca.services.data_provider:
+    class: Drupal\ai_integration_eca\Services\DataProvider\DataProvider
+    arguments:
+      - '@eca.service.modeller'
+      - '@eca.service.condition'
+      - '@eca.service.action'
+      - '@entity_type.manager'
+      - '@ai_integration_eca.services.model_mapper'
+      - '@serializer'
+      - '@token.tree_builder'
+
+  ai_integration_eca.services.eca_repository:
+    class: Drupal\ai_integration_eca\Services\EcaRepository\EcaRepository
+    arguments:
+      - '@entity_type.manager'
+      - '@ai_integration_eca.services.model_mapper'
+      - '@typed_data_manager'
+
+  ai_integration_eca.services.model_mapper:
+    class: Drupal\ai_integration_eca\Services\ModelMapper\ModelMapper
+    arguments:
+      - '@typed_data_manager'
+      - '@serializer'
+
+  # Typed data definitions in general can take many forms. This handles final items.
+  serializer.normalizer.data_definition.schema_json_ai_integration_eca.json:
+    class: Drupal\ai_integration_eca\Normalizer\json\DataDefinitionNormalizer
+    decorates: serializer.normalizer.data_definition.schema_json.json
+    arguments:
+      - '@serializer.normalizer.data_definition.schema_json_ai_integration_eca.json.inner'
diff --git a/composer.json b/composer.json
index e5b7ed2dbc60e1894151c373839413e3dc657495..b470d1004b3c951d579a24ba8d71ac63ed14ee39 100644
--- a/composer.json
+++ b/composer.json
@@ -8,15 +8,16 @@
         "source": "https://drupal.org/project/ai_integration_eca"
     },
     "require": {
-        "drupal/ai": "1.0.x-dev@dev",
-        "drupal/ai_agents": "1.0.x-dev@dev",
+        "drupal/ai": "^1.0",
         "drupal/core": "^10.3 || ^11",
         "drupal/eca": "^2.0",
         "drupal/token": "^1.15",
+        "drupal/schemata": "^1.0",
         "illuminate/support": "^10.48 || ^11.34"
     },
     "require-dev": {
-        "drupal/schemata": "^1.0",
+        "drupal/ai_agents": "^1.0",
+        "drupal/mcp": "^1.0@alpha",
         "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1"
     }
 }
diff --git a/modules/agents/ai_integration_eca_agents.info.yml b/modules/agents/ai_integration_eca_agents.info.yml
index 7366050432b3001b38d45d4457f21f8fe3f5948b..ca73bbdc31b1c1c158a62644b4ca974537025a1c 100644
--- a/modules/agents/ai_integration_eca_agents.info.yml
+++ b/modules/agents/ai_integration_eca_agents.info.yml
@@ -7,5 +7,3 @@ dependencies:
   - ai_integration_eca:ai_integration_eca
   - ai_agents:ai_agents
   - eca:eca_ui
-  - schemata:schemata_json_schema
-  - token:token
diff --git a/modules/agents/ai_integration_eca_agents.services.yml b/modules/agents/ai_integration_eca_agents.services.yml
index 3cea354a1288ad068a897cd2f8eeec853a0fc42a..99f891efaa17181da83dbc95a45a2958eb24cf5b 100644
--- a/modules/agents/ai_integration_eca_agents.services.yml
+++ b/modules/agents/ai_integration_eca_agents.services.yml
@@ -1,35 +1,4 @@
 services:
-  ai_integration_eca_agents.services.data_provider:
-    class: Drupal\ai_integration_eca_agents\Services\DataProvider\DataProvider
-    arguments:
-      - '@eca.service.modeller'
-      - '@eca.service.condition'
-      - '@eca.service.action'
-      - '@entity_type.manager'
-      - '@ai_integration_eca_agents.services.model_mapper'
-      - '@serializer'
-      - '@token.tree_builder'
-
-  ai_integration_eca_agents.services.eca_repository:
-    class: Drupal\ai_integration_eca_agents\Services\EcaRepository\EcaRepository
-    arguments:
-      - '@entity_type.manager'
-      - '@ai_integration_eca_agents.services.model_mapper'
-      - '@typed_data_manager'
-
-  ai_integration_eca_agents.services.model_mapper:
-    class: Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapper
-    arguments:
-      - '@typed_data_manager'
-      - '@serializer'
-
-  # Typed data definitions in general can take many forms. This handles final items.
-  serializer.normalizer.data_definition.schema_json_ai_integration_eca_agents.json:
-    class: Drupal\ai_integration_eca_agents\Normalizer\json\DataDefinitionNormalizer
-    decorates: serializer.normalizer.data_definition.schema_json.json
-    arguments:
-      - '@serializer.normalizer.data_definition.schema_json_ai_integration_eca_agents.json.inner'
-
   Drupal\ai_integration_eca_agents\Hook\FormHooks:
     class: Drupal\ai_integration_eca_agents\Hook\FormHooks
     autowire: true
diff --git a/modules/agents/drush.services.yml b/modules/agents/drush.services.yml
index 4be908f67c43f4832f367c02e92733395994c821..1647346ae96b5168832efff0e867e0a25d9e1d36 100644
--- a/modules/agents/drush.services.yml
+++ b/modules/agents/drush.services.yml
@@ -2,6 +2,6 @@ services:
   ai_integration_eca_agents.debug_data_provider:
     class: Drupal\ai_integration_eca_agents\Command\DebugDataProviderCommand
     arguments:
-      - '@ai_integration_eca_agents.services.data_provider'
+      - '@ai_integration_eca.services.data_provider'
     tags:
       - { name: console.command }
diff --git a/modules/agents/src/Command/DebugDataProviderCommand.php b/modules/agents/src/Command/DebugDataProviderCommand.php
index 91d47e9d8056de7d1dc2150cec6342af6baca682..04ba5af1f39d391acbb85078781acaabf7f9a0ed 100644
--- a/modules/agents/src/Command/DebugDataProviderCommand.php
+++ b/modules/agents/src/Command/DebugDataProviderCommand.php
@@ -5,8 +5,8 @@ declare(strict_types=1);
 namespace Drupal\ai_integration_eca_agents\Command;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\ai_integration_eca_agents\Services\DataProvider\DataProviderInterface;
-use Drupal\ai_integration_eca_agents\Services\DataProvider\DataViewModeEnum;
+use Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface;
+use Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum;
 use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
diff --git a/modules/agents/src/Plugin/AiAgent/Eca.php b/modules/agents/src/Plugin/AiAgent/Eca.php
index 36f70cc06995b09bf164eeae60a533b5d39a7f4a..6ea758c86877f298d0b2886679a10c6c1568d8a9 100644
--- a/modules/agents/src/Plugin/AiAgent/Eca.php
+++ b/modules/agents/src/Plugin/AiAgent/Eca.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\ai_integration_eca_agents\Plugin\AiAgent;
 
-use Drupal\ai_integration_eca_agents\Schema\Eca as EcaSchema;
-use Drupal\ai_integration_eca_agents\TypedData\EcaModelDefinition;
 use Drupal\Component\Render\MarkupInterface;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Access\AccessResult;
@@ -13,9 +11,11 @@ use Drupal\ai_agents\Attribute\AiAgent;
 use Drupal\ai_agents\PluginBase\AiAgentBase;
 use Drupal\ai_agents\PluginInterfaces\AiAgentInterface;
 use Drupal\ai_agents\Task\TaskInterface;
-use Drupal\ai_integration_eca_agents\Services\DataProvider\DataProviderInterface;
-use Drupal\ai_integration_eca_agents\Services\DataProvider\DataViewModeEnum;
-use Drupal\ai_integration_eca_agents\Services\EcaRepository\EcaRepositoryInterface;
+use Drupal\ai_integration_eca\Schema\Eca as EcaSchema;
+use Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface;
+use Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum;
+use Drupal\ai_integration_eca\Services\EcaRepository\EcaRepositoryInterface;
+use Drupal\ai_integration_eca\TypedData\EcaModelDefinition;
 use Drupal\eca\Entity\Eca as EcaEntity;
 use Illuminate\Support\Arr;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -47,14 +47,14 @@ class Eca extends AiAgentBase implements ContainerFactoryPluginInterface {
   /**
    * The ECA data provider.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\DataProvider\DataProviderInterface
+   * @var \Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface
    */
   protected DataProviderInterface $dataProvider;
 
   /**
    * The ECA helper.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\EcaRepository\EcaRepositoryInterface
+   * @var \Drupal\ai_integration_eca\Services\EcaRepository\EcaRepositoryInterface
    */
   protected EcaRepositoryInterface $ecaRepository;
 
@@ -70,8 +70,8 @@ class Eca extends AiAgentBase implements ContainerFactoryPluginInterface {
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
     $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
-    $instance->dataProvider = $container->get('ai_integration_eca_agents.services.data_provider');
-    $instance->ecaRepository = $container->get('ai_integration_eca_agents.services.eca_repository');
+    $instance->dataProvider = $container->get('ai_integration_eca.services.data_provider');
+    $instance->ecaRepository = $container->get('ai_integration_eca.services.eca_repository');
     $instance->serializer = $container->get('serializer');
     $instance->dto = [
       'task_description' => '',
diff --git a/modules/agents/src/Plugin/AiAgentValidation/EcaValidation.php b/modules/agents/src/Plugin/AiAgentValidation/EcaValidation.php
index 72119198368bb7b9f0567deaba90b28e4674bcd8..36cc30d78c13b7c9836bcb408701f54bc71e6cfe 100644
--- a/modules/agents/src/Plugin/AiAgentValidation/EcaValidation.php
+++ b/modules/agents/src/Plugin/AiAgentValidation/EcaValidation.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\ai_integration_eca_agents\Plugin\AiAgentValidation;
 
-use Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
@@ -12,6 +11,7 @@ use Drupal\ai_agents\Attribute\AiAgentValidation;
 use Drupal\ai_agents\Exception\AgentRetryableValidationException;
 use Drupal\ai_agents\PluginBase\AiAgentValidationPluginBase;
 use Drupal\ai_agents\PluginInterfaces\AiAgentValidationInterface;
+use Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface;
 use Drupal\Core\TypedData\Exception\MissingDataException;
 use Illuminate\Support\Arr;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -35,7 +35,7 @@ class EcaValidation extends AiAgentValidationPluginBase implements ContainerFact
   /**
    * The model mapper.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface
+   * @var \Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface
    */
   protected ModelMapperInterface $modelMapper;
 
@@ -45,7 +45,7 @@ class EcaValidation extends AiAgentValidationPluginBase implements ContainerFact
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): AiAgentValidationInterface {
     $instance = new static($configuration, $plugin_id, $plugin_definition);
     $instance->promptJsonDecoder = $container->get('ai.prompt_json_decode');
-    $instance->modelMapper = $container->get('ai_integration_eca_agents.services.model_mapper');
+    $instance->modelMapper = $container->get('ai_integration_eca.services.model_mapper');
 
     return $instance;
   }
diff --git a/modules/mcp/ai_integration_eca_mcp.info.yml b/modules/mcp/ai_integration_eca_mcp.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0a80b85ef22f43e372669e7353d98bafe58018db
--- /dev/null
+++ b/modules/mcp/ai_integration_eca_mcp.info.yml
@@ -0,0 +1,8 @@
+name: 'AI Integration - ECA: MCP'
+type: module
+description: 'Provide context to LLMs via the Model Context Protocol'
+core_version_requirement: ^10.3 || ^11
+package: AI
+dependencies:
+  - ai_integration_eca:ai_integration_eca
+  - mcp:mcp
diff --git a/modules/mcp/src/Plugin/Mcp/EcaMcpPluginBase.php b/modules/mcp/src/Plugin/Mcp/EcaMcpPluginBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..62b2b1c28d57b85965b7dfcc6c5c8332b1f55e3b
--- /dev/null
+++ b/modules/mcp/src/Plugin/Mcp/EcaMcpPluginBase.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\ai_integration_eca_mcp\Plugin\Mcp;
+
+use Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\mcp\Plugin\McpPluginBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Serializer\SerializerInterface;
+
+/**
+ * Abstract class for MCP-plugins using ECA-functionality.
+ */
+abstract class EcaMcpPluginBase extends McpPluginBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The data provider.
+   *
+   * @var \Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface
+   */
+  protected DataProviderInterface $dataProvider;
+
+  /**
+   * The serializer.
+   *
+   * @var \Symfony\Component\Serializer\SerializerInterface
+   */
+  protected SerializerInterface $serializer;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): EcaMcpPluginBase {
+    $instance = new static($configuration, $plugin_id, $plugin_definition);
+    $instance->dataProvider = $container->get('ai_integration_eca.services.data_provider');
+    $instance->serializer = $container->get('serializer');
+
+    return $instance;
+  }
+
+}
diff --git a/modules/mcp/src/Plugin/Mcp/EcaModelBuild.php b/modules/mcp/src/Plugin/Mcp/EcaModelBuild.php
new file mode 100644
index 0000000000000000000000000000000000000000..18f394fd4adf787c9cc272af92fef2d5fa01c47d
--- /dev/null
+++ b/modules/mcp/src/Plugin/Mcp/EcaModelBuild.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\ai_integration_eca_mcp\Plugin\Mcp;
+
+use Drupal\ai_integration_eca\Schema\Eca;
+use Drupal\ai_integration_eca\TypedData\EcaModelDefinition;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\mcp\Attribute\Mcp;
+use Drupal\mcp\ServerFeatures\Resource;
+use Drupal\mcp\ServerFeatures\Tool;
+
+/**
+ * Builds ECA models.
+ */
+#[Mcp(
+  id: 'eca-model-build',
+  name: new TranslatableMarkup('ECA Model Build'),
+  description: new TranslatableMarkup('Builds models and exposes the schema.'),
+)]
+class EcaModelBuild extends EcaMcpPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResources(): array {
+    $resources = parent::getResources();
+
+    $resources[] = new Resource(
+      uri: 'schema',
+      name: new TranslatableMarkup('ECA Model schema'),
+      description: new TranslatableMarkup('Get the schema of the ECA Model entity'),
+      mimeType: 'application/json',
+      text: NULL,
+    );
+
+    return $resources;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readResource(string $resourceId): array {
+    $definition = EcaModelDefinition::create();
+    $schema = new Eca($definition, $definition->getPropertyDefinitions());
+    $schema = $this->serializer->serialize($schema, 'schema_json:json', []);
+
+    return [
+      new Resource(
+        uri: 'schema',
+        name: new TranslatableMarkup('ECA Model schema'),
+        description: new TranslatableMarkup('Get the schema of the ECA Model entity'),
+        mimeType: 'application/json',
+        text: $schema,
+      ),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTools(): array {
+    $tools = parent::getTools();
+
+    $tools[] = new Tool(
+      name: 'schema',
+      description: new TranslatableMarkup('Retrieve the ECA Model schema.'),
+      inputSchema: [
+        'type'       => 'object',
+        'properties' => new \stdClass(),
+      ],
+    );
+
+    return $tools;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function executeTool(string $toolId, mixed $arguments): array {
+    return match ($toolId) {
+      'schema' => [['type' => 'resource', 'resource' => $this->readResource($toolId)[0]]],
+      default => parent::executeTool($toolId, $arguments),
+    };
+  }
+
+}
diff --git a/modules/mcp/src/Plugin/Mcp/EcaModelLookup.php b/modules/mcp/src/Plugin/Mcp/EcaModelLookup.php
new file mode 100644
index 0000000000000000000000000000000000000000..86f0b0e906ba4758f695b870c4d709d2bed14042
--- /dev/null
+++ b/modules/mcp/src/Plugin/Mcp/EcaModelLookup.php
@@ -0,0 +1,253 @@
+<?php
+
+namespace Drupal\ai_integration_eca_mcp\Plugin\Mcp;
+
+use Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\mcp\Attribute\Mcp;
+use Drupal\mcp\ServerFeatures\Resource;
+use Drupal\mcp\ServerFeatures\ResourceTemplate;
+use Drupal\mcp\ServerFeatures\Tool;
+use Illuminate\Support\Arr;
+
+/**
+ * Exposes ECA models.
+ */
+#[Mcp(
+  id: 'eca-model-lookup',
+  name: new TranslatableMarkup('ECA Model Lookup'),
+  description: new TranslatableMarkup('Provides Models as a Resource or via lookup tools'),
+)]
+class EcaModelLookup extends EcaMcpPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration(): array {
+    $config = parent::defaultConfiguration();
+
+    $config['config']['only_enabled'] = TRUE;
+
+    return $config;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
+    $config = $this->getConfiguration();
+
+    $form = parent::buildConfigurationForm($form, $form_state);
+    $form['only_enabled'] = [
+      '#type' => 'checkbox',
+      '#title' => new TranslatableMarkup('Only expose enabled models'),
+      '#default_value' => $config['config']['only_enabled'] ?? TRUE,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResources(): array {
+    $resources = parent::getResources();
+
+    $resources[] = new Resource(
+      uri: 'model',
+      name: new TranslatableMarkup('@definition: Models', [
+        '@definition' => $this->getPluginDefinition()['name'],
+      ]),
+      description: new TranslatableMarkup('Get all models.'),
+      mimeType: 'application/json',
+      text: NULL,
+    );
+
+    return $resources;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResourceTemplates(): array {
+    $templates = parent::getResourceTemplates();
+
+    $templates[] = new ResourceTemplate(
+      uriTemplate: 'model/{id}',
+      name: sprintf('%s: Model', $this->getPluginDefinition()['name']),
+      description: new TranslatableMarkup('Get a specific model.'),
+      mimeType: 'application/json',
+    );
+
+    return $templates;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readResource(string $resourceId): array {
+    // Fetch resource and sub-resource from the provided URI.
+    // - 'eca-model-lookup://model'. 'event' is the resource ID.
+    // - 'eca-model-lookup://model/process_ilwj9jq':
+    // -- 'model' is the resource ID.
+    // -- 'process_ilwj9jq' is the sub-resource.
+    $result = preg_match("#^(?'resource_id'[^/]+)(?:/(?'sub_resource'.*))?$#", $resourceId, $matches);
+    if (!$result) {
+      throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId));
+    }
+
+    // If a sub-resource is requested, fetch it from the database and return the
+    // full data object.
+    $data = [];
+    $uri = '';
+    if (!empty($matches['sub_resource'])) {
+      $this->dataProvider->setViewMode(DataViewModeEnum::Full);
+      $data = $this->dataProvider->getModels([$matches['sub_resource']], $this->getConfiguration()['config']['only_enabled']);
+      $uri = $resourceId;
+
+      if (empty($data)) {
+        throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId));
+      }
+    }
+
+    // If a generic resource is requested, fetch them from the codebase and
+    // return a slimmed down list of plugins.
+    if (empty($data)) {
+      $this->dataProvider->setViewMode(DataViewModeEnum::Teaser);
+      $data = $this->dataProvider->getModels([], $this->getConfiguration()['config']['only_enabled']);
+    }
+
+    // Wrap everything in a Resource.
+    $response = [];
+    foreach ($data as $model) {
+      $response[] = new Resource(
+        uri: empty($uri) ? sprintf('%s/%s', $resourceId, $model['model_id']) : $uri,
+        name: $model['label'],
+        description: $model['description'] ?? '',
+        mimeType: 'application/json',
+        text: json_encode(Arr::except($model, [
+          'model_id',
+          'label',
+          'description',
+        ])),
+      );
+    }
+
+    return $response;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTools(): array {
+    $tools = parent::getTools();
+
+    $tools[] = new Tool(
+      name: 'lookup',
+      description: new TranslatableMarkup('Lookup ECA models using filters. Multiple filters are combined with AND logic.'),
+      inputSchema: [
+        'type' => 'object',
+        'properties' => [
+          'filters' => [
+            'type' => 'array',
+            'description' => new TranslatableMarkup('Array of filter conditions.'),
+            'items' => [
+              'type' => 'object',
+              'required' => ['field', 'value'],
+              'properties' => [
+                'field' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Field name to filter on.'),
+                  'enum' => [
+                    'label',
+                  ],
+                ],
+                'value' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Value to filter by.'),
+                ],
+                'operator' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Comparison operator.'),
+                  'default' => '=',
+                  'enum' => [
+                    '=',
+                    '<>',
+                    'CONTAINS',
+                    'STARTS_WITH',
+                    'ENDS_WITH',
+                  ],
+                ],
+              ],
+            ],
+          ],
+          'limit' => [
+            'type' => 'integer',
+            'description' => new TranslatableMarkup('Maximum number of results'),
+            'default' => 10,
+          ],
+          'offset' => [
+            'type' => 'integer',
+            'description' => new TranslatableMarkup('Starting point for pagination'),
+            'default' => 0,
+          ],
+        ],
+      ],
+    );
+
+    return $tools;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function executeTool(string $toolId, mixed $arguments): array {
+    return match ($toolId) {
+      'lookup' => $this->lookupModels($arguments),
+      default => parent::executeTool($toolId, $arguments),
+    };
+  }
+
+  /**
+   * Lookup models by applying filtering arguments.
+   *
+   * @param array $arguments
+   *   The filters.
+   *
+   * @return array
+   *   Returns an array of resources.
+   */
+  protected function lookupModels(array $arguments): array {
+    assert(!empty($arguments['filters']), new TranslatableMarkup('Filters must be an array.'));
+
+    $filters = $arguments['filters'];
+
+    if ($this->getConfiguration()['config']['only_enabled']) {
+      $filters[] = [
+        'field' => 'status',
+        'value' => TRUE,
+      ];
+    }
+
+    try {
+      $models = $this->dataProvider->filterModels($filters, $arguments['limit'] ?? 10, $arguments['offset'] ?? 0);
+    }
+    catch (\Exception $e) {
+      return [
+        'type' => 'text',
+        'text' => sprintf('Error: %s', $e->getMessage()),
+      ];
+    }
+
+    return array_reduce($models, function (array $carry, $model) {
+      $carry[] = [
+        'type' => 'resource',
+        'resource' => $this->readResource(sprintf('model/%s', $model['model_id']))[0],
+      ];
+
+      return $carry;
+    }, []);
+  }
+
+}
diff --git a/modules/mcp/src/Plugin/Mcp/EcaPluginLookup.php b/modules/mcp/src/Plugin/Mcp/EcaPluginLookup.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b170b55c311eeae81d9b4b62a7ca63b6c46c163
--- /dev/null
+++ b/modules/mcp/src/Plugin/Mcp/EcaPluginLookup.php
@@ -0,0 +1,324 @@
+<?php
+
+namespace Drupal\ai_integration_eca_mcp\Plugin\Mcp;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\ai_integration_eca\EcaElementType;
+use Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum;
+use Drupal\mcp\Attribute\Mcp;
+use Drupal\mcp\ServerFeatures\Resource;
+use Drupal\mcp\ServerFeatures\ResourceTemplate;
+use Drupal\mcp\ServerFeatures\Tool;
+use Illuminate\Support\Arr;
+
+/**
+ * Exposes ECA plugins.
+ */
+#[Mcp(
+  id: 'eca-plugin-lookup',
+  name: new TranslatableMarkup('ECA Plugin Lookup'),
+  description: new TranslatableMarkup('Provides Events, Conditions and Actions as a Resource or via lookup tools'),
+)]
+class EcaPluginLookup extends EcaMcpPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration(): array {
+    $config = parent::defaultConfiguration();
+
+    $config['config']['plugin_types'] = array_keys(EcaElementType::getCoreTypes());
+
+    return $config;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
+    $config = $this->getConfiguration();
+
+    $form = parent::buildConfigurationForm($form, $form_state);
+    $form['plugin_types'] = [
+      '#type' => 'checkboxes',
+      '#title' => new TranslatableMarkup('Plugin types'),
+      '#options' => EcaElementType::getCoreTypes(),
+      '#default_value' => $config['config']['plugin_types'] ?? array_keys(EcaElementType::getCoreTypes()),
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResources(): array {
+    $resources = parent::getResources();
+    $pluginTypes = $this->getAvailablePluginTypes();
+
+    foreach ($pluginTypes as $pluginType) {
+      $resources[] = new Resource(
+        uri: $pluginType,
+        name: new TranslatableMarkup('@definition: @name', [
+          '@definition' => $this->getPluginDefinition()['name'],
+          '@name' => ucfirst(EcaElementType::from($pluginType)->getPlural()),
+        ]),
+        description: new TranslatableMarkup("Get all implementations of plugin type '@type'", [
+          '@type' => $pluginType,
+        ]),
+        mimeType: 'application/json',
+        text: NULL,
+      );
+    }
+
+    return $resources;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResourceTemplates(): array {
+    $templates = parent::getResourceTemplates();
+    $pluginTypes = $this->getAvailablePluginTypes();
+
+    foreach ($pluginTypes as $pluginType) {
+      $templates[] = new ResourceTemplate(
+        uriTemplate: sprintf('%s/{id}', $pluginType),
+        name: sprintf('%s: %s', $this->getPluginDefinition()['name'], EcaElementType::from($pluginType)->name),
+        description: new TranslatableMarkup("Get a specific implementation of plugin type '@type'", [
+          '@type' => $pluginType,
+        ]),
+        mimeType: 'application/json',
+      );
+    }
+
+    return $templates;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readResource(string $resourceId): array {
+    // Fetch resource and sub-resource from the provided URI.
+    // - 'eca-plugin-lookup://event'. 'event' is the resource ID.
+    // - 'eca-plugin-lookup://event/content_entity:presave':
+    // -- 'event' is the resource ID.
+    // -- 'content_entity:presave' is the sub-resource.
+    $result = preg_match("#^(?'resource_id'[^/]+)(?:/(?'sub_resource'.*))?$#", $resourceId, $matches);
+    if (!$result) {
+      throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId));
+    }
+
+    if (!$this->isPluginTypeEnabled($matches['resource_id'])) {
+      throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId));
+    }
+
+    // If a sub-resource is requested, fetch it from the codebase and return the
+    // full data object.
+    $data = [];
+    $uri = '';
+    if (!empty($matches['sub_resource'])) {
+      $this->dataProvider->setViewMode(DataViewModeEnum::Full);
+      $data = $this->dataProvider->getComponents([$matches['sub_resource']]);
+      $data = $data[EcaElementType::from($matches['resource_id'])->getPlural()];
+      $uri = $resourceId;
+
+      if (empty($data)) {
+        throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId));
+      }
+    }
+
+    // If a generic resource is requested, fetch them from the codebase and
+    // return a slimmed down list of plugins.
+    if (empty($data)) {
+      $this->dataProvider->setViewMode(DataViewModeEnum::Teaser);
+      $data = match (EcaElementType::from($resourceId)) {
+        EcaElementType::Event => $this->dataProvider->getEvents(),
+        EcaElementType::Condition => $this->dataProvider->getConditions(),
+        EcaElementType::Action => $this->dataProvider->getActions(),
+        default => throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $resourceId)),
+      };
+    }
+
+    // Wrap everything in a Resource.
+    $response = [];
+    foreach ($data as $plugin) {
+      $response[] = new Resource(
+        uri: empty($uri) ? sprintf('%s/%s', $resourceId, $plugin['plugin_id']) : $uri,
+        name: $plugin['name'],
+        description: $plugin['description'] ?? '',
+        mimeType: 'application/json',
+        text: json_encode(Arr::except($plugin, ['plugin_id', 'name', 'description'])),
+      );
+    }
+
+    return $response;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTools(): array {
+    $tools = parent::getTools();
+
+    $tools[] = new Tool(
+      name: 'lookup',
+      description: new TranslatableMarkup('Lookup ECA plugins using filters. Multiple filters are combined with AND logic.'),
+      inputSchema: [
+        'type' => 'object',
+        'required' => ['pluginType'],
+        'properties' => [
+          'pluginType' => [
+            'type' => 'string',
+            'description' => new TranslatableMarkup('Plugin type name. Available options: @options.', [
+              '@options' => implode(', ', array_keys(EcaElementType::getCoreTypes())),
+            ]),
+          ],
+          'filters' => [
+            'type' => 'array',
+            'description' => new TranslatableMarkup('Array of filter conditions.'),
+            'items' => [
+              'type' => 'object',
+              'required' => ['field', 'value'],
+              'properties' => [
+                'field' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Field name to filter on.'),
+                  'enum' => [
+                    'plugin_id',
+                    'name',
+                    'module',
+                  ],
+                ],
+                'value' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Value to filter by.'),
+                ],
+                'operator' => [
+                  'type' => 'string',
+                  'description' => new TranslatableMarkup('Comparison operator.'),
+                  'default' => '=',
+                  'enum' => [
+                    '=',
+                    '<>',
+                    'CONTAINS',
+                    'STARTS_WITH',
+                    'ENDS_WITH',
+                  ],
+                ],
+              ],
+            ],
+          ],
+          'limit' => [
+            'type' => 'integer',
+            'description' => new TranslatableMarkup('Maximum number of results'),
+            'default' => 10,
+          ],
+          'offset' => [
+            'type' => 'integer',
+            'description' => new TranslatableMarkup('Starting point for pagination'),
+            'default' => 0,
+          ],
+        ],
+      ],
+    );
+
+    return $tools;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function executeTool(string $toolId, mixed $arguments): array {
+    return match ($toolId) {
+      'lookup' => $this->lookupPlugins($arguments),
+      default => [],
+    };
+  }
+
+  /**
+   * Lookup plugins by applying filtering arguments.
+   *
+   * @param array $arguments
+   *   The filters.
+   *
+   * @return array
+   *   Returns an array of resources.
+   */
+  protected function lookupPlugins(array $arguments): array {
+    assert(!empty($arguments['pluginType']), new TranslatableMarkup('Plugin type must be a string.'));
+    assert($this->isPluginTypeEnabled($arguments['pluginType']), sprintf("Plugin type '%s' is not enabled.", $arguments['pluginType']));
+
+    $pluginType = $arguments['pluginType'];
+    $this->dataProvider->setViewMode(DataViewModeEnum::Full);
+    $data = match (EcaElementType::from($pluginType)) {
+      EcaElementType::Event => $this->dataProvider->getEvents(),
+      EcaElementType::Condition => $this->dataProvider->getConditions(),
+      EcaElementType::Action => $this->dataProvider->getActions(),
+      default => throw new \InvalidArgumentException(sprintf('Unknown resource ID: %s', $pluginType)),
+    };
+
+    if (empty($data)) {
+      return [
+        'type' => 'text',
+        'text' => new TranslatableMarkup('Error: no applicable plugins found.'),
+      ];
+    }
+
+    $data = collect($data);
+    foreach ($arguments['filters'] ?? [] as $filter) {
+      assert(!empty($filter['field']), new TranslatableMarkup('A filter needs to be defined by a field.'));
+      assert(!empty($filter['value']), new TranslatableMarkup('A filter needs to be defined by a value.'));
+
+      $data = match ($filter['operator'] ?? '=') {
+        'CONTAINS' => $data->filter(function (array $plugin) use ($filter) {
+          return !empty($plugin[$filter['field']]) && str_contains(mb_strtolower($plugin[$filter['field']]), mb_strtolower($filter['value']));
+        }),
+        'STARTS_WITH' => $data->filter(function (array $plugin) use ($filter) {
+          return !empty($plugin[$filter['field']]) && str_starts_with(mb_strtolower($plugin[$filter['field']]), mb_strtolower($filter['value']));
+        }),
+        'ENDS_WITH' => $data->filter(function (array $plugin) use ($filter) {
+          return !empty($plugin[$filter['field']]) && str_ends_with(mb_strtolower($plugin[$filter['field']]), mb_strtolower($filter['value']));
+        }),
+        '=' => $data->where($filter['field'], '===', $filter['value']),
+        default => $data->where($filter['field'], $filter['operator'], $filter['value']),
+      };
+    }
+
+    return $data
+      ->slice($arguments['offset'] ?? 0, $arguments['limit'] ?? 10)
+      ->reduce(function (array $carry, array $plugin) use ($pluginType) {
+      $carry[] = [
+        'type' => 'resource',
+        'resource' => $this->readResource(sprintf('%s/%s', $pluginType, $plugin['plugin_id']))[0],
+      ];
+
+      return $carry;
+    }, []);
+  }
+
+  /**
+   * Get the available plugin types.
+   *
+   * @return array
+   *   Returns the available plugin types.
+   */
+  protected function getAvailablePluginTypes(): array {
+    return array_filter(array_values($this->getConfiguration()['config']['plugin_types']));
+  }
+
+  /**
+   * Determine if a plugin type is enabled.
+   *
+   * @param string $pluginType
+   *   The plugin type to validate.
+   *
+   * @return bool
+   *   Returns whether the plugin type is enabled.
+   */
+  protected function isPluginTypeEnabled(string $pluginType): bool {
+    return in_array($pluginType, $this->getAvailablePluginTypes(), TRUE);
+  }
+
+}
diff --git a/modules/agents/src/EcaElementType.php b/src/EcaElementType.php
similarity index 68%
rename from modules/agents/src/EcaElementType.php
rename to src/EcaElementType.php
index a18e3f469566ed670e47f3c2e65f49589b31b303..3c08aa31642bff59519f1be48b8d356f57ff950f 100644
--- a/modules/agents/src/EcaElementType.php
+++ b/src/EcaElementType.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents;
+namespace Drupal\ai_integration_eca;
 
 /**
  * Enum of the element types.
@@ -30,7 +30,7 @@ enum EcaElementType: string {
   /**
    * Returns a list of types, keyed by their plural form.
    *
-   * @return \Drupal\ai_integration_eca_agents\EcaElementType[]
+   * @return \Drupal\ai_integration_eca\EcaElementType[]
    *   The list of types, keyed by their plural form.
    */
   public static function getPluralMap(): array {
@@ -42,4 +42,18 @@ enum EcaElementType: string {
     ];
   }
 
+  /**
+   * Returns a list of core types.
+   *
+   * @return array
+   *   the list of core types.
+   */
+  public static function getCoreTypes(): array {
+    return [
+      self::Event->value => self::Event->name,
+      self::Condition->value => self::Condition->name,
+      self::Action->value => self::Action->name,
+    ];
+  }
+
 }
diff --git a/modules/agents/src/EntityViolationException.php b/src/EntityViolationException.php
similarity index 97%
rename from modules/agents/src/EntityViolationException.php
rename to src/EntityViolationException.php
index 433bb4ba7139cb1fb5c3ea7c7464e602c2195445..86967a56e4cbcb30956a3fd05c59d602425ea6ca 100644
--- a/modules/agents/src/EntityViolationException.php
+++ b/src/EntityViolationException.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents;
+namespace Drupal\ai_integration_eca;
 
 use Drupal\Core\Config\ConfigException;
 use Symfony\Component\Validator\ConstraintViolationListInterface;
diff --git a/modules/agents/src/MissingEventException.php b/src/MissingEventException.php
similarity index 78%
rename from modules/agents/src/MissingEventException.php
rename to src/MissingEventException.php
index 06d79611e60aacdfd0f5edef0b1fb3db667b49a4..92fef32ec7fa291e9185f0e549d888bc457d4efe 100644
--- a/modules/agents/src/MissingEventException.php
+++ b/src/MissingEventException.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents;
+namespace Drupal\ai_integration_eca;
 
 use Drupal\Core\Config\ConfigException;
 
diff --git a/modules/agents/src/Normalizer/json/DataDefinitionNormalizer.php b/src/Normalizer/json/DataDefinitionNormalizer.php
similarity index 97%
rename from modules/agents/src/Normalizer/json/DataDefinitionNormalizer.php
rename to src/Normalizer/json/DataDefinitionNormalizer.php
index ff359822e30b45e8b9af65cd8db695ce4ebb1d7c..b8adf0e38e2754038665f110a2ee2b1eef7a2137 100644
--- a/modules/agents/src/Normalizer/json/DataDefinitionNormalizer.php
+++ b/src/Normalizer/json/DataDefinitionNormalizer.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Normalizer\json;
+namespace Drupal\ai_integration_eca\Normalizer\json;
 
 use Drupal\Core\TypedData\DataDefinitionInterface;
 use Drupal\schemata_json_schema\Normalizer\json\JsonNormalizerBase;
diff --git a/src/Plugin/Action/AiConfigActionBase.php b/src/Plugin/Action/AiConfigActionBase.php
index 7b4a8ce93bab00b196e81a285af0659521d2a1ac..6c3464f796622aa8cebfbc8297cacf544e97ceb9 100644
--- a/src/Plugin/Action/AiConfigActionBase.php
+++ b/src/Plugin/Action/AiConfigActionBase.php
@@ -6,7 +6,7 @@ use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\ai_integration_eca\Service\AiProviderValidatorInterface;
+use Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidatorInterface;
 use Drupal\eca\Service\YamlParser;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Validator\ConstraintViolationInterface;
@@ -27,7 +27,7 @@ abstract class AiConfigActionBase extends AiActionBase {
   /**
    * The AI Provider validator.
    *
-   * @var \Drupal\ai_integration_eca\Service\AiProviderValidatorInterface
+   * @var \Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidatorInterface
    */
   protected AiProviderValidatorInterface $validator;
 
@@ -37,7 +37,7 @@ abstract class AiConfigActionBase extends AiActionBase {
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
     $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
     $instance->yamlParser = $container->get('eca.service.yaml_parser');
-    $instance->validator = $container->get('ai_integration_eca.provider_validator');
+    $instance->validator = $container->get('ai_integration_eca.services.provider_validator');
 
     return $instance;
   }
diff --git a/modules/agents/src/Plugin/DataType/EcaGateway.php b/src/Plugin/DataType/EcaGateway.php
similarity index 74%
rename from modules/agents/src/Plugin/DataType/EcaGateway.php
rename to src/Plugin/DataType/EcaGateway.php
index b06c35a597273fc9cf7afbd110abad3ab832a292..87f0dfedcad17403ae770001f4549f70a453c427 100644
--- a/modules/agents/src/Plugin/DataType/EcaGateway.php
+++ b/src/Plugin/DataType/EcaGateway.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\DataType;
+namespace Drupal\ai_integration_eca\Plugin\DataType;
 
-use Drupal\ai_integration_eca_agents\TypedData\EcaGatewayDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaGatewayDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\Attribute\DataType;
 use Drupal\Core\TypedData\Plugin\DataType\Map;
diff --git a/modules/agents/src/Plugin/DataType/EcaModel.php b/src/Plugin/DataType/EcaModel.php
similarity index 81%
rename from modules/agents/src/Plugin/DataType/EcaModel.php
rename to src/Plugin/DataType/EcaModel.php
index 43fd34cde7744dc599adc74ed18331919f1672d2..bcd12cb279b6445a470975b1e7dd532351ade590 100644
--- a/modules/agents/src/Plugin/DataType/EcaModel.php
+++ b/src/Plugin/DataType/EcaModel.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\DataType;
+namespace Drupal\ai_integration_eca\Plugin\DataType;
 
-use Drupal\ai_integration_eca_agents\TypedData\EcaModelDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaModelDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\Attribute\DataType;
 use Drupal\Core\TypedData\Plugin\DataType\Map;
diff --git a/modules/agents/src/Plugin/DataType/EcaPlugin.php b/src/Plugin/DataType/EcaPlugin.php
similarity index 83%
rename from modules/agents/src/Plugin/DataType/EcaPlugin.php
rename to src/Plugin/DataType/EcaPlugin.php
index f4bdac8a730dcb016ab9758488ad8e901552fd92..efc2b816de0cf914f53c798be4766604121d76c9 100644
--- a/modules/agents/src/Plugin/DataType/EcaPlugin.php
+++ b/src/Plugin/DataType/EcaPlugin.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\DataType;
+namespace Drupal\ai_integration_eca\Plugin\DataType;
 
-use Drupal\ai_integration_eca_agents\TypedData\EcaPluginDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaPluginDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\Attribute\DataType;
 use Drupal\Core\TypedData\Plugin\DataType\Map;
diff --git a/modules/agents/src/Plugin/DataType/EcaSuccessor.php b/src/Plugin/DataType/EcaSuccessor.php
similarity index 74%
rename from modules/agents/src/Plugin/DataType/EcaSuccessor.php
rename to src/Plugin/DataType/EcaSuccessor.php
index 0c4e959c90d98f859ed9f1884c5a9a410386f02d..5c2fbf8bfb69a5847cc92c10f131a923f44cda51 100644
--- a/modules/agents/src/Plugin/DataType/EcaSuccessor.php
+++ b/src/Plugin/DataType/EcaSuccessor.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\DataType;
+namespace Drupal\ai_integration_eca\Plugin\DataType;
 
-use Drupal\ai_integration_eca_agents\TypedData\EcaSuccessorDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaSuccessorDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\Attribute\DataType;
 use Drupal\Core\TypedData\Plugin\DataType\Map;
diff --git a/modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php b/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php
similarity index 94%
rename from modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php
rename to src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php
index a4745c85bb1be1c9858250ab8f5fd8417e96261d..ec586a30fa653386ba1aa0f682837a6ecd62b53f 100644
--- a/modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php
+++ b/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraint.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\Validation\Constraint;
+namespace Drupal\ai_integration_eca\Plugin\Validation\Constraint;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Validation\Attribute\Constraint;
diff --git a/modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php b/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php
similarity index 91%
rename from modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php
rename to src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php
index 4a8bc4823362c7c0de585ecc0e2fb94679e79648..8b5181c3b388ad310d05be2e2786fafdf11e9fc5 100644
--- a/modules/agents/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php
+++ b/src/Plugin/Validation/Constraint/SuccessorsAreValidConstraintValidator.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Plugin\Validation\Constraint;
+namespace Drupal\ai_integration_eca\Plugin\Validation\Constraint;
 
-use Drupal\ai_integration_eca_agents\EcaElementType;
+use Drupal\ai_integration_eca\EcaElementType;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
 
@@ -38,11 +38,11 @@ class SuccessorsAreValidConstraintValidator extends ConstraintValidator {
   /**
    * Validate the successors of an element.
    *
-   * @param \Drupal\ai_integration_eca_agents\Plugin\Validation\Constraint\SuccessorsAreValidConstraint $constraint
+   * @param \Drupal\ai_integration_eca\Plugin\Validation\Constraint\SuccessorsAreValidConstraint $constraint
    *   The constraint.
    * @param array $element
    *   The element to validate.
-   * @param \Drupal\ai_integration_eca_agents\EcaElementType $type
+   * @param \Drupal\ai_integration_eca\EcaElementType $type
    *   The type of the element.
    * @param array $lookup
    *   The lookup-array containing all the referencable IDs.
diff --git a/modules/agents/src/Schema/Eca.php b/src/Schema/Eca.php
similarity index 97%
rename from modules/agents/src/Schema/Eca.php
rename to src/Schema/Eca.php
index b1bb9cc02c143e92a8acd248d514146bfc840036..5a3e773ebf52c870b930abe1b589d25f002fd7b7 100644
--- a/modules/agents/src/Schema/Eca.php
+++ b/src/Schema/Eca.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Schema;
+namespace Drupal\ai_integration_eca\Schema;
 
 use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
 use Drupal\Core\TypedData\DataDefinitionInterface;
diff --git a/src/Service/AiProviderValidator.php b/src/Services/AiProviderValidator/AiProviderValidator.php
similarity index 98%
rename from src/Service/AiProviderValidator.php
rename to src/Services/AiProviderValidator/AiProviderValidator.php
index fd1355238252786af9136dd8b79760f433b85690..0b3613f1a3090af02b33721b457a96855e2e9d60 100644
--- a/src/Service/AiProviderValidator.php
+++ b/src/Services/AiProviderValidator/AiProviderValidator.php
@@ -1,16 +1,12 @@
 <?php
 
-namespace Drupal\ai_integration_eca\Service;
+namespace Drupal\ai_integration_eca\Services\AiProviderValidator;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Validation\BasicRecursiveValidatorFactory;
 use Drupal\ai\AiProviderInterface;
 use Drupal\ai\Plugin\ProviderProxy;
 use Symfony\Component\Validator\Constraint;
-use Symfony\Component\Validator\ConstraintViolation;
-use Symfony\Component\Validator\ConstraintViolationInterface;
-use Symfony\Component\Validator\ConstraintViolationList;
-use Symfony\Component\Validator\ConstraintViolationListInterface;
 use Symfony\Component\Validator\Constraints\Choice;
 use Symfony\Component\Validator\Constraints\Collection;
 use Symfony\Component\Validator\Constraints\NotBlank;
@@ -18,6 +14,10 @@ use Symfony\Component\Validator\Constraints\Optional;
 use Symfony\Component\Validator\Constraints\Range;
 use Symfony\Component\Validator\Constraints\Required;
 use Symfony\Component\Validator\Constraints\Type;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\ConstraintViolationListInterface;
 use Symfony\Component\Validator\Validator\ValidatorInterface;
 
 /**
diff --git a/src/Service/AiProviderValidatorInterface.php b/src/Services/AiProviderValidator/AiProviderValidatorInterface.php
similarity index 88%
rename from src/Service/AiProviderValidatorInterface.php
rename to src/Services/AiProviderValidator/AiProviderValidatorInterface.php
index e396df3950beaabfdbfb5d2769313630b8a61796..e95f6931a8f005be91d8033037eea5dc06d6c5be 100644
--- a/src/Service/AiProviderValidatorInterface.php
+++ b/src/Services/AiProviderValidator/AiProviderValidatorInterface.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca\Service;
+namespace Drupal\ai_integration_eca\Services\AiProviderValidator;
 
 use Drupal\ai\AiProviderInterface;
 use Drupal\ai\Plugin\ProviderProxy;
@@ -34,7 +34,7 @@ interface AiProviderValidatorInterface {
    * @param array<string, \Symfony\Component\Validator\Constraint> $constraints
    *   Additional constraints to set, keyed by field.
    *
-   * @return \Drupal\ai\Service\AiProviderValidator\AiProviderValidatorInterface
+   * @return \Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidatorInterface
    *   Returns the called object.
    */
   public function addConstraints(array $constraints): AiProviderValidatorInterface;
diff --git a/modules/agents/src/Services/DataProvider/DataProvider.php b/src/Services/DataProvider/DataProvider.php
similarity index 78%
rename from modules/agents/src/Services/DataProvider/DataProvider.php
rename to src/Services/DataProvider/DataProvider.php
index 15d421c848f6362c4843b78a2f2d87df493edbaf..8008e3f238797b76e0976300b7cb49ab1621252b 100644
--- a/modules/agents/src/Services/DataProvider/DataProvider.php
+++ b/src/Services/DataProvider/DataProvider.php
@@ -1,14 +1,16 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\DataProvider;
+namespace Drupal\ai_integration_eca\Services\DataProvider;
 
-use Drupal\ai_integration_eca_agents\EcaElementType;
 use Drupal\Component\Plugin\ConfigurableInterface;
 use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Plugin\PluginFormInterface;
-use Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface;
+use Drupal\ai_integration_eca\EcaElementType;
+use Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\eca\Attributes\Token;
 use Drupal\eca\Entity\Eca;
 use Drupal\eca\Service\Actions;
@@ -26,7 +28,7 @@ class DataProvider implements DataProviderInterface {
   /**
    * The view mode which determines how many details are returned.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\DataProvider\DataViewModeEnum
+   * @var \Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum
    */
   protected DataViewModeEnum $viewMode = DataViewModeEnum::Teaser;
 
@@ -41,7 +43,7 @@ class DataProvider implements DataProviderInterface {
    *   The actions.
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
    *   The entity type manager.
-   * @param \Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface $modelMapper
+   * @param \Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface $modelMapper
    *   The model mapper.
    * @param \Symfony\Component\Serializer\Normalizer\NormalizerInterface $normalizer
    *   The normalizer.
@@ -125,7 +127,7 @@ class DataProvider implements DataProviderInterface {
   /**
    * {@inheritdoc}
    */
-  public function getModels(array $filterIds = []): array {
+  public function getModels(array $filterIds = [], $onlyEnabled = TRUE): array {
     /** @var \Drupal\eca\Entity\EcaStorage $storage */
     $storage = $this->entityTypeManager->getStorage('eca');
     $models = $storage->loadMultiple();
@@ -136,18 +138,39 @@ class DataProvider implements DataProviderInterface {
       });
     }
 
-    return array_reduce($models, function (array $carry, Eca $eca) {
-      $model = $this->modelMapper->fromEntity($eca);
-      $data = array_filter($this->normalizer->normalize($model));
+    if ($onlyEnabled) {
+      $models = array_filter($models, function (Eca $model) {
+        return $model->status();
+      });
+    }
 
-      if ($this->viewMode === DataViewModeEnum::Teaser) {
-        $data = Arr::only($data, ['model_id', 'label', 'description']);
-      }
+    return $this->reduceModels($models);
+  }
 
-      $carry[] = $data;
+  /**
+   * {@inheritdoc}
+   */
+  public function filterModels(array $filters, int $limit = 10, int $offset = 0): array {
+    $query = $this->entityTypeManager->getStorage('eca')->getQuery()
+      ->accessCheck(FALSE)
+      ->range($offset, $limit);
 
-      return $carry;
-    }, []);
+    foreach ($filters as $filter) {
+      assert(!empty($filter['field']), new TranslatableMarkup('A filter needs to be defined by a field.'));
+      assert(!empty($filter['value']), new TranslatableMarkup('A filter needs to be defined by a value.'));
+
+      assert($this->entityTypeManager->getDefinition('eca')->hasKey($filter['field']), new TranslatableMarkup('Unknown field: @field.', [
+        '@field' => $filter['field'],
+      ]));
+
+      $query->condition($filter['field'], $filter['value'], $filter['operator'] ?? '=');
+    }
+
+    $ids = $query->execute();
+    $models = $this->entityTypeManager->getStorage('eca')
+      ->loadMultiple($ids);
+
+    return $this->reduceModels($models);
   }
 
   /**
@@ -254,4 +277,29 @@ class DataProvider implements DataProviderInterface {
     }, []);
   }
 
+  /**
+   * Reduce a collection of ECA models.
+   *
+   * @param \Drupal\eca\Entity\Eca[] $models
+   *
+   * @return array
+   *   Returns a reduced collection of ECA model data.
+   *
+   * @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
+   */
+  protected function reduceModels(array $models): array {
+    return array_reduce($models, function (array $carry, Eca $eca) {
+      $model = $this->modelMapper->fromEntity($eca);
+      $data = array_filter($this->normalizer->normalize($model));
+
+      if ($this->viewMode === DataViewModeEnum::Teaser) {
+        $data = Arr::only($data, ['model_id', 'label', 'description']);
+      }
+
+      $carry[] = $data;
+
+      return $carry;
+    }, []);
+  }
+
 }
diff --git a/modules/agents/src/Services/DataProvider/DataProviderInterface.php b/src/Services/DataProvider/DataProviderInterface.php
similarity index 64%
rename from modules/agents/src/Services/DataProvider/DataProviderInterface.php
rename to src/Services/DataProvider/DataProviderInterface.php
index d6b76010ddc090201e853f869e5433c603a9e1a3..13337efb2f390865961edcb9b5461b2214c32c06 100644
--- a/modules/agents/src/Services/DataProvider/DataProviderInterface.php
+++ b/src/Services/DataProvider/DataProviderInterface.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\DataProvider;
+namespace Drupal\ai_integration_eca\Services\DataProvider;
 
 /**
  * Interface for ECA data provider.
@@ -47,11 +47,28 @@ interface DataProviderInterface {
    *
    * @param array $filterIds
    *   An optional array of IDs to filter by.
+   * @param bool $onlyEnabled
+   *   Only return the enabled models.
    *
    * @return array
    *   Returns the models.
    */
-  public function getModels(array $filterIds = []): array;
+  public function getModels(array $filterIds = [], bool $onlyEnabled = TRUE): array;
+
+  /**
+   * Filter models.
+   *
+   * @param array $filters
+   *   An optional array of field- and value-options to filter by.
+   * @param int $limit
+   *   The amount of models to filter.
+   * @param int $offset
+   *   The starting point for pagination
+   *
+   * @return array
+   *   Returns the models.
+   */
+  public function filterModels(array $filters, int $limit = 10, int $offset = 0): array;
 
   /**
    * Get the available tokens.
@@ -67,10 +84,10 @@ interface DataProviderInterface {
    * This is used for controlling how much details are exposed for the different
    * components.
    *
-   * @param \Drupal\ai_integration_eca_agents\Services\DataProvider\DataViewModeEnum $viewMode
+   * @param \Drupal\ai_integration_eca\Services\DataProvider\DataViewModeEnum $viewMode
    *   The view mode.
    *
-   * @return \Drupal\ai_integration_eca_agents\Services\DataProvider\DataProviderInterface
+   * @return \Drupal\ai_integration_eca\Services\DataProvider\DataProviderInterface
    *   Returns the altered instance.
    */
   public function setViewMode(DataViewModeEnum $viewMode): DataProviderInterface;
diff --git a/modules/agents/src/Services/DataProvider/DataViewModeEnum.php b/src/Services/DataProvider/DataViewModeEnum.php
similarity index 70%
rename from modules/agents/src/Services/DataProvider/DataViewModeEnum.php
rename to src/Services/DataProvider/DataViewModeEnum.php
index dd50a156517fcb0e609e7c672849fd0c77056388..910d59c301bc7835730402923f9639cec0947c26 100644
--- a/modules/agents/src/Services/DataProvider/DataViewModeEnum.php
+++ b/src/Services/DataProvider/DataViewModeEnum.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\DataProvider;
+namespace Drupal\ai_integration_eca\Services\DataProvider;
 
 /**
  * Enumeration determining the view mode of the data.
diff --git a/modules/agents/src/Services/EcaRepository/EcaRepository.php b/src/Services/EcaRepository/EcaRepository.php
similarity index 85%
rename from modules/agents/src/Services/EcaRepository/EcaRepository.php
rename to src/Services/EcaRepository/EcaRepository.php
index 834eb51aec2174c336b7d691893d7549a2089e60..69f36cb089e3432eeecfbed84411aa9bee47fc28 100644
--- a/modules/agents/src/Services/EcaRepository/EcaRepository.php
+++ b/src/Services/EcaRepository/EcaRepository.php
@@ -1,13 +1,13 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\EcaRepository;
+namespace Drupal\ai_integration_eca\Services\EcaRepository;
 
-use Drupal\ai_integration_eca_agents\EntityViolationException;
-use Drupal\ai_integration_eca_agents\MissingEventException;
-use Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface;
 use Drupal\Component\Utility\Random;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\TypedData\TypedDataManagerInterface;
+use Drupal\ai_integration_eca\EntityViolationException;
+use Drupal\ai_integration_eca\MissingEventException;
+use Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface;
 use Drupal\eca\Entity\Eca;
 
 /**
@@ -20,7 +20,7 @@ class EcaRepository implements EcaRepositoryInterface {
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
    *   The entity type manager.
-   * @param \Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface $modelMapper
+   * @param \Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface $modelMapper
    *   The model mapper.
    * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager
    *   The typed data manager.
@@ -65,7 +65,7 @@ class EcaRepository implements EcaRepositoryInterface {
     $eca->resetComponents();
 
     // Set events.
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $plugin */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $plugin */
     foreach ($model->get('events') as $plugin) {
       $successors = $plugin->get('successors')->getValue() ?? [];
       foreach ($successors as &$successor) {
@@ -84,7 +84,7 @@ class EcaRepository implements EcaRepositoryInterface {
     }
 
     // Set conditions.
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $plugin */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $plugin */
     foreach ($model->get('conditions') as $plugin) {
       $eca->addCondition(
         $plugin->get('element_id')->getString(),
@@ -94,7 +94,7 @@ class EcaRepository implements EcaRepositoryInterface {
     }
 
     // Set gateways.
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaGateway $plugin */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaGateway $plugin */
     foreach ($model->get('gateways') as $plugin) {
       $successors = $plugin->get('successors')->getValue() ?? [];
       foreach ($successors as &$successor) {
@@ -111,7 +111,7 @@ class EcaRepository implements EcaRepositoryInterface {
     }
 
     // Set actions.
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaGateway $plugin */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaGateway $plugin */
     foreach ($model->get('actions') as $plugin) {
       $successors = $plugin->get('successors')->getValue() ?? [];
       foreach ($successors as &$successor) {
diff --git a/modules/agents/src/Services/EcaRepository/EcaRepositoryInterface.php b/src/Services/EcaRepository/EcaRepositoryInterface.php
similarity index 91%
rename from modules/agents/src/Services/EcaRepository/EcaRepositoryInterface.php
rename to src/Services/EcaRepository/EcaRepositoryInterface.php
index 9b4cfadb13c0ad97d8d67449e5b1125d43b9151f..f6055a83451ab32a02063d2a1caf802736f66d7d 100644
--- a/modules/agents/src/Services/EcaRepository/EcaRepositoryInterface.php
+++ b/src/Services/EcaRepository/EcaRepositoryInterface.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\EcaRepository;
+namespace Drupal\ai_integration_eca\Services\EcaRepository;
 
 use Drupal\eca\Entity\Eca;
 
diff --git a/modules/agents/src/Services/ModelMapper/ModelMapper.php b/src/Services/ModelMapper/ModelMapper.php
similarity index 86%
rename from modules/agents/src/Services/ModelMapper/ModelMapper.php
rename to src/Services/ModelMapper/ModelMapper.php
index 56fcc8d5672aff81a4aaa283e852ade3170ed507..9069a31e05feb8bbd2c20942ab2004d065d68b4e 100644
--- a/modules/agents/src/Services/ModelMapper/ModelMapper.php
+++ b/src/Services/ModelMapper/ModelMapper.php
@@ -1,13 +1,13 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\ModelMapper;
-
-use Drupal\ai_integration_eca_agents\EcaElementType;
-use Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel;
-use Drupal\ai_integration_eca_agents\TypedData\EcaGatewayDefinition;
-use Drupal\ai_integration_eca_agents\TypedData\EcaModelDefinition;
-use Drupal\ai_integration_eca_agents\TypedData\EcaPluginDefinition;
-use Drupal\ai_integration_eca_agents\TypedData\EcaSuccessorDefinition;
+namespace Drupal\ai_integration_eca\Services\ModelMapper;
+
+use Drupal\ai_integration_eca\EcaElementType;
+use Drupal\ai_integration_eca\Plugin\DataType\EcaModel;
+use Drupal\ai_integration_eca\TypedData\EcaGatewayDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaModelDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaPluginDefinition;
+use Drupal\ai_integration_eca\TypedData\EcaSuccessorDefinition;
 use Drupal\Core\TypedData\ComplexDataInterface;
 use Drupal\Core\TypedData\Exception\MissingDataException;
 use Drupal\Core\TypedData\TypedDataManagerInterface;
@@ -40,7 +40,7 @@ class ModelMapper implements ModelMapperInterface {
    */
   public function fromPayload(array $payload): EcaModel {
     $definition = EcaModelDefinition::create();
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel $model */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaModel $model */
     $model = $this->typedDataManager->create($definition, $payload);
 
     /** @var \Symfony\Component\Validator\ConstraintViolationList $violations */
@@ -57,7 +57,7 @@ class ModelMapper implements ModelMapperInterface {
    */
   public function fromEntity(Eca $entity): EcaModel {
     $modelDef = EcaModelDefinition::create();
-    /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel $model */
+    /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaModel $model */
     $model = $this->typedDataManager->create($modelDef);
 
     // Basic properties.
@@ -73,7 +73,7 @@ class ModelMapper implements ModelMapperInterface {
 
       $def = EcaPluginDefinition::create();
       $def->setSetting('data_type', EcaElementType::Event);
-      /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $model */
+      /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $model */
       $model = $this->typedDataManager->create($def);
       $model->set('element_id', $event->getId());
       $model->set('plugin_id', $event->getPlugin()->getPluginId());
@@ -92,7 +92,7 @@ class ModelMapper implements ModelMapperInterface {
     $plugins = array_reduce(array_keys($conditions), function (array $carry, string $conditionId) use ($conditions) {
       $def = EcaPluginDefinition::create();
       $def->setSetting('data_type', EcaElementType::Condition);
-      /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $model */
+      /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $model */
       $model = $this->typedDataManager->create($def);
       $model->set('element_id', $conditionId);
       $model->set('plugin_id', $conditions[$conditionId]['plugin']);
@@ -111,7 +111,7 @@ class ModelMapper implements ModelMapperInterface {
 
       $def = EcaPluginDefinition::create();
       $def->setSetting('data_type', EcaElementType::Action);
-      /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $model */
+      /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $model */
       $model = $this->typedDataManager->create($def);
       $model->set('element_id', $actionId);
       $model->set('plugin_id', $actions[$actionId]['plugin']);
@@ -130,7 +130,7 @@ class ModelMapper implements ModelMapperInterface {
     $plugins = array_reduce(array_keys($gateways), function (array $carry, string $gatewayId) use ($gateways) {
       $successors = $this->mapSuccessorsToModel($gateways[$gatewayId]['successors']);
 
-      /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaPlugin $model */
+      /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaPlugin $model */
       $model = $this->typedDataManager->create(EcaGatewayDefinition::create());
       $model->set('gateway_id', $gatewayId);
       $model->set('type', $gateways[$gatewayId]['type']);
@@ -186,7 +186,7 @@ class ModelMapper implements ModelMapperInterface {
    */
   protected function mapSuccessorsToModel(array $successors): array {
     return array_filter(array_reduce($successors, function ($carry, array $successor) {
-      /** @var \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaSuccessor $model */
+      /** @var \Drupal\ai_integration_eca\Plugin\DataType\EcaSuccessor $model */
       $model = $this->typedDataManager->create(EcaSuccessorDefinition::create());
       $model->set('element_id', $successor['id']);
       $model->set('condition', $successor['condition']);
diff --git a/modules/agents/src/Services/ModelMapper/ModelMapperInterface.php b/src/Services/ModelMapper/ModelMapperInterface.php
similarity index 68%
rename from modules/agents/src/Services/ModelMapper/ModelMapperInterface.php
rename to src/Services/ModelMapper/ModelMapperInterface.php
index ac67052ddf1137863dedb044daa2266173d47597..aad07e37c313ea22d42050120f22836d8ed310a5 100644
--- a/modules/agents/src/Services/ModelMapper/ModelMapperInterface.php
+++ b/src/Services/ModelMapper/ModelMapperInterface.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\Services\ModelMapper;
+namespace Drupal\ai_integration_eca\Services\ModelMapper;
 
-use Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel;
+use Drupal\ai_integration_eca\Plugin\DataType\EcaModel;
 use Drupal\eca\Entity\Eca;
 
 /**
@@ -16,7 +16,7 @@ interface ModelMapperInterface {
    * @param array $payload
    *   The external payload.
    *
-   * @return \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel
+   * @return \Drupal\ai_integration_eca\Plugin\DataType\EcaModel
    *   Returns the ECA Model typed data.
    */
   public function fromPayload(array $payload): EcaModel;
@@ -27,7 +27,7 @@ interface ModelMapperInterface {
    * @param \Drupal\eca\Entity\Eca $entity
    *   The ECA entity.
    *
-   * @return \Drupal\ai_integration_eca_agents\Plugin\DataType\EcaModel
+   * @return \Drupal\ai_integration_eca\Plugin\DataType\EcaModel
    *   Returns the ECA Model typed data.
    */
   public function fromEntity(Eca $entity): EcaModel;
diff --git a/modules/agents/src/TypedData/EcaGatewayDefinition.php b/src/TypedData/EcaGatewayDefinition.php
similarity index 96%
rename from modules/agents/src/TypedData/EcaGatewayDefinition.php
rename to src/TypedData/EcaGatewayDefinition.php
index d7ef72ac7d03020fa3f108b5d754b268cdbb5d0c..119fd79db3c8e1103d5e5ac30e877f9a3ef1682c 100644
--- a/modules/agents/src/TypedData/EcaGatewayDefinition.php
+++ b/src/TypedData/EcaGatewayDefinition.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\TypedData;
+namespace Drupal\ai_integration_eca\TypedData;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\ComplexDataDefinitionBase;
diff --git a/modules/agents/src/TypedData/EcaModelDefinition.php b/src/TypedData/EcaModelDefinition.php
similarity index 96%
rename from modules/agents/src/TypedData/EcaModelDefinition.php
rename to src/TypedData/EcaModelDefinition.php
index 3bb7c35ab843e09b5304c898ce56b398d37ca669..9eb2527b8ad2175c08ac1e67ff813a82b99a449b 100644
--- a/modules/agents/src/TypedData/EcaModelDefinition.php
+++ b/src/TypedData/EcaModelDefinition.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\TypedData;
+namespace Drupal\ai_integration_eca\TypedData;
 
-use Drupal\ai_integration_eca_agents\EcaElementType;
+use Drupal\ai_integration_eca\EcaElementType;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\ComplexDataDefinitionBase;
 use Drupal\Core\TypedData\DataDefinition;
diff --git a/modules/agents/src/TypedData/EcaPluginDefinition.php b/src/TypedData/EcaPluginDefinition.php
similarity index 97%
rename from modules/agents/src/TypedData/EcaPluginDefinition.php
rename to src/TypedData/EcaPluginDefinition.php
index fabe07b49a4639dbcbeb978c69cb7335ce7bbb8f..7b0d623683e4591324bc47c89699597af943e296 100644
--- a/modules/agents/src/TypedData/EcaPluginDefinition.php
+++ b/src/TypedData/EcaPluginDefinition.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\TypedData;
+namespace Drupal\ai_integration_eca\TypedData;
 
-use Drupal\ai_integration_eca_agents\EcaElementType;
+use Drupal\ai_integration_eca\EcaElementType;
 use Drupal\Core\Action\ActionInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\ComplexDataDefinitionBase;
diff --git a/modules/agents/src/TypedData/EcaSuccessorDefinition.php b/src/TypedData/EcaSuccessorDefinition.php
similarity index 95%
rename from modules/agents/src/TypedData/EcaSuccessorDefinition.php
rename to src/TypedData/EcaSuccessorDefinition.php
index c056813f855b3a3b38766465f92b24c26a128aa4..13541294c931ad4d40f59ce778536a2aafecfdb7 100644
--- a/modules/agents/src/TypedData/EcaSuccessorDefinition.php
+++ b/src/TypedData/EcaSuccessorDefinition.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\ai_integration_eca_agents\TypedData;
+namespace Drupal\ai_integration_eca\TypedData;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\ComplexDataDefinitionBase;
diff --git a/modules/agents/tests/assets/from_payload_0.json b/tests/assets/from_payload_0.json
similarity index 100%
rename from modules/agents/tests/assets/from_payload_0.json
rename to tests/assets/from_payload_0.json
diff --git a/modules/agents/tests/assets/from_payload_1.json b/tests/assets/from_payload_1.json
similarity index 100%
rename from modules/agents/tests/assets/from_payload_1.json
rename to tests/assets/from_payload_1.json
diff --git a/modules/agents/tests/assets/from_payload_2.json b/tests/assets/from_payload_2.json
similarity index 100%
rename from modules/agents/tests/assets/from_payload_2.json
rename to tests/assets/from_payload_2.json
diff --git a/modules/agents/tests/assets/from_payload_3.json b/tests/assets/from_payload_3.json
similarity index 100%
rename from modules/agents/tests/assets/from_payload_3.json
rename to tests/assets/from_payload_3.json
diff --git a/modules/agents/tests/assets/from_payload_4.json b/tests/assets/from_payload_4.json
similarity index 100%
rename from modules/agents/tests/assets/from_payload_4.json
rename to tests/assets/from_payload_4.json
diff --git a/tests/src/Kernel/Plugin/Action/AiActionTestBase.php b/tests/src/Kernel/Plugin/Action/AiActionTestBase.php
index 2f137f32b5d74cda256e24dba851a0334ee83fd2..eb7f4739e5bc14a16eac3a941bf8bd055dcc531f 100644
--- a/tests/src/Kernel/Plugin/Action/AiActionTestBase.php
+++ b/tests/src/Kernel/Plugin/Action/AiActionTestBase.php
@@ -21,7 +21,11 @@ abstract class AiActionTestBase extends KernelTestBase {
     'eca',
     'file',
     'key',
+    'schemata',
+    'schemata_json_schema',
+    'serialization',
     'system',
+    'token',
     'user',
   ];
 
diff --git a/modules/agents/tests/src/Kernel/AiEcaAgentsKernelTestBase.php b/tests/src/Kernel/Services/AiIntegrationEcaServicesKernelTestBase.php
similarity index 74%
rename from modules/agents/tests/src/Kernel/AiEcaAgentsKernelTestBase.php
rename to tests/src/Kernel/Services/AiIntegrationEcaServicesKernelTestBase.php
index fd75d73c1491c72366fd9293a5ddd49770a03687..d0869b0d0995ce77813a90f482f92db895f46011 100644
--- a/modules/agents/tests/src/Kernel/AiEcaAgentsKernelTestBase.php
+++ b/tests/src/Kernel/Services/AiIntegrationEcaServicesKernelTestBase.php
@@ -1,22 +1,21 @@
 <?php
 
-namespace Drupal\Tests\ai_integration_eca_agents\Kernel;
+namespace Drupal\Tests\ai_integration_eca\Kernel\Services;
 
 use Drupal\Component\Serialization\Json;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\NodeType;
 
 /**
- * Base class for Kernel-tests regarding AI ECA Agents.
+ * Base class for Kernel-tests regarding AI Integration - ECA.
  */
-abstract class AiEcaAgentsKernelTestBase extends KernelTestBase {
+abstract class AiIntegrationEcaServicesKernelTestBase extends KernelTestBase {
 
   /**
    * {@inheritdoc}
    */
   protected static $modules = [
     'ai_integration_eca',
-    'ai_integration_eca_agents',
     'eca',
     'eca_base',
     'eca_content',
@@ -41,7 +40,7 @@ abstract class AiEcaAgentsKernelTestBase extends KernelTestBase {
    */
   public static function payloadProvider(): \Generator {
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_0.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_0.json', __DIR__))),
       [
         'events' => 1,
         'conditions' => 0,
@@ -51,21 +50,21 @@ abstract class AiEcaAgentsKernelTestBase extends KernelTestBase {
     ];
 
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_1.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_1.json', __DIR__))),
       [],
       NULL,
       'model_id: This value should not be null',
     ];
 
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_2.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_2.json', __DIR__))),
       [],
       NULL,
       'events: This value should not be null',
     ];
 
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_3.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_3.json', __DIR__))),
       [
         'events' => 1,
         'conditions' => 1,
@@ -76,7 +75,7 @@ abstract class AiEcaAgentsKernelTestBase extends KernelTestBase {
     ];
 
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_3.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_3.json', __DIR__))),
       [
         'events' => 1,
         'conditions' => 1,
@@ -89,7 +88,7 @@ abstract class AiEcaAgentsKernelTestBase extends KernelTestBase {
     ];
 
     yield [
-      Json::decode(file_get_contents(sprintf('%s/../../assets/from_payload_4.json', __DIR__))),
+      Json::decode(file_get_contents(sprintf('%s/../../../assets/from_payload_4.json', __DIR__))),
       [],
       NULL,
       "Invalid successor ID 'condition_check_title' for Event 'event_page_published'. Must reference a gateway or action.",
diff --git a/tests/src/Kernel/Service/AiProviderValidatorTest.php b/tests/src/Kernel/Services/AiProviderValidatorTest.php
similarity index 88%
rename from tests/src/Kernel/Service/AiProviderValidatorTest.php
rename to tests/src/Kernel/Services/AiProviderValidatorTest.php
index 94a23576568c43dabf798ac4adc0b3e76f053dd1..ae30ff3dc71cbe0a4902f1ff9f1eaf9de48494bb 100644
--- a/tests/src/Kernel/Service/AiProviderValidatorTest.php
+++ b/tests/src/Kernel/Services/AiProviderValidatorTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\Tests\ai_integration_eca\Kernel\Service;
+namespace Drupal\Tests\ai_integration_eca\Kernel\Services;
 
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\TestTools\Random;
 use Drupal\ai\AiProviderPluginManager;
-use Drupal\ai_integration_eca\Service\AiProviderValidatorInterface;
+use Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidatorInterface;
 use Symfony\Component\Validator\Constraints\Required;
 use Symfony\Component\Validator\Constraints\Type;
 
@@ -21,10 +21,15 @@ class AiProviderValidatorTest extends KernelTestBase {
    */
   protected static $modules = [
     'ai',
-    'ai_test',
     'ai_integration_eca',
+    'ai_test',
+    'eca',
     'key',
+    'schemata',
+    'schemata_json_schema',
+    'serialization',
     'system',
+    'token',
     'user',
   ];
 
@@ -38,7 +43,7 @@ class AiProviderValidatorTest extends KernelTestBase {
   /**
    * The AI Provider validator.
    *
-   * @var \Drupal\ai\Service\AiProviderValidator\AiProviderValidatorInterface|null
+   * @var \Drupal\ai_integration_eca\Services\AiProviderValidator\AiProviderValidatorInterface|null
    */
   protected ?AiProviderValidatorInterface $validator;
 
@@ -51,8 +56,8 @@ class AiProviderValidatorTest extends KernelTestBase {
     $this->installEntitySchema('user');
     $this->installConfig(static::$modules);
 
-    $this->aiProvider = \Drupal::service('ai.provider');
-    $this->validator = \Drupal::service('ai_integration_eca.provider_validator');
+    $this->aiProvider = $this->container->get('ai.provider');
+    $this->validator = $this->container->get('ai_integration_eca.services.provider_validator');
   }
 
   /**
diff --git a/modules/agents/tests/src/Kernel/EcaModelSchemaTest.php b/tests/src/Kernel/Services/EcaModelSchemaTest.php
similarity index 83%
rename from modules/agents/tests/src/Kernel/EcaModelSchemaTest.php
rename to tests/src/Kernel/Services/EcaModelSchemaTest.php
index 64c8212f1805b11c9e1ec1b3e9ae39df693cb92d..8cc74fb704bfdd1d544fe728e56b29bdb2253875 100644
--- a/modules/agents/tests/src/Kernel/EcaModelSchemaTest.php
+++ b/tests/src/Kernel/Services/EcaModelSchemaTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\Tests\ai_integration_eca_agents\Kernel;
+namespace Drupal\Tests\ai_integration_eca\Kernel\Services;
 
-use Drupal\ai_integration_eca_agents\Schema\Eca as EcaSchema;
-use Drupal\ai_integration_eca_agents\TypedData\EcaModelDefinition;
 use Drupal\KernelTests\KernelTestBase;
+use Drupal\ai_integration_eca\Schema\Eca as EcaSchema;
+use Drupal\ai_integration_eca\TypedData\EcaModelDefinition;
 use Spatie\Snapshots\MatchesSnapshots;
 use Symfony\Component\Serializer\SerializerInterface;
 
 /**
  * Kernel test for the ECA Model data type.
  *
- * @group ai_integration_eca_agents
+ * @group ai_integration_eca
  */
 class EcaModelSchemaTest extends KernelTestBase {
 
@@ -22,7 +22,6 @@ class EcaModelSchemaTest extends KernelTestBase {
    */
   protected static $modules = [
     'ai_integration_eca',
-    'ai_integration_eca_agents',
     'eca',
     'serialization',
     'schemata',
diff --git a/modules/agents/tests/src/Kernel/EcaRepositoryTest.php b/tests/src/Kernel/Services/EcaRepositoryTest.php
similarity index 69%
rename from modules/agents/tests/src/Kernel/EcaRepositoryTest.php
rename to tests/src/Kernel/Services/EcaRepositoryTest.php
index 0b01899ebe52b2be0f9d2142e6e45cc34af56c14..bb1dcd7e93d2e0cc3c82965927150505c510950e 100644
--- a/modules/agents/tests/src/Kernel/EcaRepositoryTest.php
+++ b/tests/src/Kernel/Services/EcaRepositoryTest.php
@@ -1,20 +1,20 @@
 <?php
 
-namespace Drupal\Tests\ai_integration_eca_agents\Kernel;
+namespace Drupal\Tests\ai_integration_eca\Kernel\Services;
 
-use Drupal\ai_integration_eca_agents\Services\EcaRepository\EcaRepositoryInterface;
+use Drupal\ai_integration_eca\Services\EcaRepository\EcaRepositoryInterface;
 
 /**
  * Tests various input data for generating ECA models.
  *
- * @group ai_integration_eca_agents
+ * @group ai_integration_eca
  */
-class EcaRepositoryTest extends AiEcaAgentsKernelTestBase {
+class EcaRepositoryTest extends AiIntegrationEcaServicesKernelTestBase {
 
   /**
    * The ECA repository.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\EcaRepository\EcaRepositoryInterface|null
+   * @var \Drupal\ai_integration_eca\Services\EcaRepository\EcaRepositoryInterface|null
    */
   protected ?EcaRepositoryInterface $ecaRepository;
 
@@ -49,7 +49,7 @@ class EcaRepositoryTest extends AiEcaAgentsKernelTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->ecaRepository = \Drupal::service('ai_integration_eca_agents.services.eca_repository');
+    $this->ecaRepository = $this->container->get('ai_integration_eca.services.eca_repository');
   }
 
 }
diff --git a/modules/agents/tests/src/Kernel/ModelMapperTest.php b/tests/src/Kernel/Services/ModelMapperTest.php
similarity index 83%
rename from modules/agents/tests/src/Kernel/ModelMapperTest.php
rename to tests/src/Kernel/Services/ModelMapperTest.php
index 9e726498dbc29c8b5f96d2bd3afcd84eb56260d6..34c118f4414cd39da8e710e47ccfc42dcbbea579 100644
--- a/modules/agents/tests/src/Kernel/ModelMapperTest.php
+++ b/tests/src/Kernel/Services/ModelMapperTest.php
@@ -1,18 +1,18 @@
 <?php
 
-namespace Drupal\Tests\ai_integration_eca_agents\Kernel;
+namespace Drupal\Tests\ai_integration_eca\Kernel\Services;
 
-use Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface;
 use Spatie\Snapshots\MatchesSnapshots;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 
 /**
  * Tests various input data for generation ECA Model typed data.
  *
- * @group ai_integration_eca_agents
+ * @group ai_integration_eca
  */
-class ModelMapperTest extends AiEcaAgentsKernelTestBase {
+class ModelMapperTest extends AiIntegrationEcaServicesKernelTestBase {
 
   use MatchesSnapshots;
 
@@ -21,7 +21,6 @@ class ModelMapperTest extends AiEcaAgentsKernelTestBase {
    */
   protected static $modules = [
     'ai_integration_eca',
-    'ai_integration_eca_agents',
     'eca',
     'eca_base',
     'eca_content',
@@ -44,7 +43,7 @@ class ModelMapperTest extends AiEcaAgentsKernelTestBase {
   /**
    * The model mapper.
    *
-   * @var \Drupal\ai_integration_eca_agents\Services\ModelMapper\ModelMapperInterface|null
+   * @var \Drupal\ai_integration_eca\Services\ModelMapper\ModelMapperInterface|null
    */
   protected ?ModelMapperInterface $modelMapper;
 
@@ -128,9 +127,9 @@ class ModelMapperTest extends AiEcaAgentsKernelTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->modelMapper = \Drupal::service('ai_integration_eca_agents.services.model_mapper');
-    $this->entityTypeManager = \Drupal::entityTypeManager();
-    $this->normalizer = \Drupal::service('serializer');
+    $this->modelMapper = $this->container->get('ai_integration_eca.services.model_mapper');
+    $this->entityTypeManager = $this->container->get('entity_type.manager');
+    $this->normalizer = $this->container->get('serializer');
   }
 
 }
diff --git a/modules/agents/tests/src/Kernel/__snapshots__/EcaModelSchemaTest__testSchema__1.json b/tests/src/Kernel/Services/__snapshots__/EcaModelSchemaTest__testSchema__1.json
similarity index 100%
rename from modules/agents/tests/src/Kernel/__snapshots__/EcaModelSchemaTest__testSchema__1.json
rename to tests/src/Kernel/Services/__snapshots__/EcaModelSchemaTest__testSchema__1.json
diff --git a/modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 0__1.json b/tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 0__1.json
similarity index 100%
rename from modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 0__1.json
rename to tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 0__1.json
diff --git a/modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 1__1.json b/tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 1__1.json
similarity index 100%
rename from modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 1__1.json
rename to tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 1__1.json
diff --git a/modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 2__1.json b/tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 2__1.json
similarity index 100%
rename from modules/agents/tests/src/Kernel/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 2__1.json
rename to tests/src/Kernel/Services/__snapshots__/ModelMapperTest__testMappingFromEntity with data set 2__1.json