diff --git a/src/components/FunctionalArea/NavBar/NavBar.component.tsx b/src/components/FunctionalArea/NavBar/NavBar.component.tsx
index fbc5c000ee41e1dd810219d5d9cf181263fc02a7..830131c1ac047fd046c01ee9e585b48d876cf8c5 100644
--- a/src/components/FunctionalArea/NavBar/NavBar.component.tsx
+++ b/src/components/FunctionalArea/NavBar/NavBar.component.tsx
@@ -15,7 +15,7 @@ export const NavBar = (): JSX.Element => {
   };
 
   const openDrawerPlugins = (): void => {
-    dispatch(openDrawer('plugins'));
+    dispatch(openDrawer('available-plugins'));
   };
 
   const openDrawerExport = (): void => {
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..06d70d35abe59da6cf05b3c3700d991746cc3db8
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx
@@ -0,0 +1,53 @@
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { AvailablePluginsDrawer } from './AvailablePluginsDrawer.component';
+
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <AvailablePluginsDrawer />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('AvailablePluginsDrawer - component', () => {
+  describe('when always', () => {
+    it('should render drawer heading', () => {
+      renderComponent(INITIAL_STORE_STATE_MOCK);
+      const drawerTitle = screen.getByText('Available plugins');
+      expect(drawerTitle).toBeInTheDocument();
+    });
+
+    it('should render load plugin from url', () => {
+      renderComponent(INITIAL_STORE_STATE_MOCK);
+      const loadPluginFromUrlInput = screen.getByTestId('load-plugin-input-url');
+      expect(loadPluginFromUrlInput).toBeInTheDocument();
+    });
+
+    it.each(PLUGINS_MOCK)('should render render all public plugins', currentPlugin => {
+      renderComponent({
+        ...INITIAL_STORE_STATE_MOCK,
+        plugins: {
+          ...INITIAL_STORE_STATE_MOCK.plugins,
+          list: {
+            ...INITIAL_STORE_STATE_MOCK.plugins.list,
+            data: PLUGINS_MOCK,
+          },
+        },
+      });
+
+      const pluginLabel = screen.getByText(currentPlugin.name);
+      expect(pluginLabel).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d1343d91bbf51f36f926c2af248d596790155f04
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.tsx
@@ -0,0 +1,21 @@
+import { publicPluginsListSelector } from '@/redux/plugins/plugins.selectors';
+import { DrawerHeading } from '@/shared/DrawerHeading';
+import { useSelector } from 'react-redux';
+import { LoadPlugin } from './LoadPlugin';
+import { LoadPluginFromUrl } from './LoadPluginFromUrl';
+
+export const AvailablePluginsDrawer = (): JSX.Element => {
+  const publicPlugins = useSelector(publicPluginsListSelector);
+
+  return (
+    <div className="h-full max-h-full" data-testid="available-plugins-drawer">
+      <DrawerHeading title="Available plugins" />
+      <div className="flex flex-col gap-6 p-6">
+        <LoadPluginFromUrl />
+        {publicPlugins.map(plugin => (
+          <LoadPlugin key={plugin.hash} plugin={plugin} />
+        ))}
+      </div>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..92c659ac76bde94184d4324be245989f7c8f4dec
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx
@@ -0,0 +1,29 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import { render, screen } from '@testing-library/react';
+import { LoadPlugin, Props } from './LoadPlugin.component';
+
+const renderComponent = ({ plugin }: Props): void => {
+  render(<LoadPlugin plugin={plugin} />);
+};
+
+describe('LoadPlugin - component', () => {
+  describe('when always', () => {
+    const plugin = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+    it('renders plugin name', () => {
+      renderComponent({ plugin });
+
+      const title = screen.getByText(plugin.name);
+      expect(title).toBeInTheDocument();
+    });
+
+    it('renders plugin load button', () => {
+      renderComponent({ plugin });
+
+      const loadButton = screen.getByText('Load');
+      expect(loadButton.tagName).toBe('BUTTON');
+      expect(loadButton).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fee403ca18cb34195aaf42a559ba618eb68f821e
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx
@@ -0,0 +1,25 @@
+import { Button } from '@/shared/Button';
+import { MinervaPlugin } from '@/types/models';
+
+export interface Props {
+  plugin: MinervaPlugin;
+}
+
+export const LoadPlugin = ({ plugin }: Props): JSX.Element => {
+  const handleLoadPlugin = (): void => {
+    // TODO: handleLoadPlugin
+  };
+
+  return (
+    <div className="flex w-full items-center justify-between">
+      <span className="text-cetacean-blue">{plugin.name}</span>
+      <Button
+        variantStyles="secondary"
+        className="h-10 self-end rounded-e rounded-s"
+        onClick={handleLoadPlugin}
+      >
+        Load
+      </Button>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/index.ts b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e27e6ba35e4443188bf5a6e08a655ddb97b3262c
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/index.ts
@@ -0,0 +1 @@
+export { LoadPlugin } from './LoadPlugin.component';
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..e1d83a8ba9fde4258d36ad1d5df8629ac583ce57
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx
@@ -0,0 +1,32 @@
+import { render, screen } from '@testing-library/react';
+import { LoadPluginFromUrl } from './LoadPluginFromUrl.component';
+
+const renderComponent = (): void => {
+  render(<LoadPluginFromUrl />);
+};
+
+describe('LoadPluginFromUrl - component', () => {
+  describe('when always', () => {
+    it('renders plugin input label', () => {
+      renderComponent();
+
+      const pluginInputLabel = screen.getByLabelText('URL:');
+      expect(pluginInputLabel).toBeInTheDocument();
+    });
+
+    it('renders plugin input', () => {
+      renderComponent();
+
+      const pluginInput = screen.getByTestId('load-plugin-input-url');
+      expect(pluginInput).toBeInTheDocument();
+    });
+
+    it('renders plugin load button', () => {
+      renderComponent();
+
+      const loadButton = screen.getByText('Load');
+      expect(loadButton.tagName).toBe('BUTTON');
+      expect(loadButton).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..de486ad2bb19462bca3674a24f9a72a126d1f75c
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.tsx
@@ -0,0 +1,32 @@
+import { Button } from '@/shared/Button';
+import { useState } from 'react';
+
+export const LoadPluginFromUrl = (): JSX.Element => {
+  const [url, setUrl] = useState<string>('');
+
+  const handleLoadPlugin = (): void => {
+    // TODO: handleLoadPlugin
+  };
+
+  return (
+    <div className="flex w-full">
+      <label className="flex w-full flex-col gap-2 text-sm text-cetacean-blue">
+        <span>URL:</span>
+        <input
+          className="h-10 w-full bg-cultured p-3"
+          type="url"
+          value={url}
+          onChange={(e): void => setUrl(e.target.value)}
+          data-testid="load-plugin-input-url"
+        />
+      </label>
+      <Button
+        variantStyles="secondary"
+        className="h-10 self-end rounded-e rounded-s"
+        onClick={handleLoadPlugin}
+      >
+        Load
+      </Button>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/index.ts b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cedb0f665553574022fb55f4f00ef9678b546f1d
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/index.ts
@@ -0,0 +1 @@
+export { LoadPluginFromUrl } from './LoadPluginFromUrl.component';
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/index.ts b/src/components/Map/Drawer/AvailablePluginsDrawer/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..85f2fe7f30853779b57a030199940cd3055f8e3a
--- /dev/null
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/index.ts
@@ -0,0 +1 @@
+export { AvailablePluginsDrawer } from './AvailablePluginsDrawer.component';
diff --git a/src/components/Map/Drawer/Drawer.component.tsx b/src/components/Map/Drawer/Drawer.component.tsx
index 098c4f989ec233798af6de0addfbb28fca84b02e..de1aa94ea44f6f9e2203ea3a386e373cbce620d6 100644
--- a/src/components/Map/Drawer/Drawer.component.tsx
+++ b/src/components/Map/Drawer/Drawer.component.tsx
@@ -2,13 +2,14 @@ import { DRAWER_ROLE } from '@/components/Map/Drawer/Drawer.constants';
 import { drawerSelector } from '@/redux/drawer/drawer.selectors';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { twMerge } from 'tailwind-merge';
-import { ReactionDrawer } from './ReactionDrawer';
-import { SearchDrawerWrapper as SearchDrawerContent } from './SearchDrawerWrapper';
-import { SubmapsDrawer } from './SubmapsDrawer';
-import { OverlaysDrawer } from './OverlaysDrawer';
+import { AvailablePluginsDrawer } from './AvailablePluginsDrawer';
 import { BioEntityDrawer } from './BioEntityDrawer/BioEntityDrawer.component';
 import { ExportDrawer } from './ExportDrawer';
+import { OverlaysDrawer } from './OverlaysDrawer';
 import { ProjectInfoDrawer } from './ProjectInfoDrawer';
+import { ReactionDrawer } from './ReactionDrawer';
+import { SearchDrawerWrapper as SearchDrawerContent } from './SearchDrawerWrapper';
+import { SubmapsDrawer } from './SubmapsDrawer';
 
 export const Drawer = (): JSX.Element => {
   const { isOpen, drawerName } = useAppSelector(drawerSelector);
@@ -28,6 +29,7 @@ export const Drawer = (): JSX.Element => {
       {isOpen && drawerName === 'bio-entity' && <BioEntityDrawer />}
       {isOpen && drawerName === 'project-info' && <ProjectInfoDrawer />}
       {isOpen && drawerName === 'export' && <ExportDrawer />}
+      {isOpen && drawerName === 'available-plugins' && <AvailablePluginsDrawer />}
     </div>
   );
 };
diff --git a/src/models/mocks/pluginsMock.ts b/src/models/mocks/pluginsMock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5c91eafdb32833dff36caedddfc4b85d9bac2f6
--- /dev/null
+++ b/src/models/mocks/pluginsMock.ts
@@ -0,0 +1,44 @@
+import { MinervaPlugin } from '@/types/models';
+
+export const PLUGINS_MOCK: MinervaPlugin[] = [
+  {
+    hash: '5e3fcb59588cc311ef9839feea6382eb',
+    name: 'Disease-variant associations',
+    version: '1.0.0',
+    isPublic: true,
+    isDefault: false,
+    urls: ['https://minerva-service.lcsb.uni.lu/plugins/disease-associations/plugin.js'],
+  },
+  {
+    hash: '20df86476c311824bbfe73d1034af89e',
+    name: 'GSEA',
+    version: '0.9.2',
+    isPublic: true,
+    isDefault: false,
+    urls: ['https://minerva-service.lcsb.uni.lu/plugins/gsea/plugin.js'],
+  },
+  {
+    hash: '5314b9f996e56e67f0dad65e7df8b73b',
+    name: 'PD map guide',
+    version: '1.0.2',
+    isPublic: true,
+    isDefault: false,
+    urls: ['https://minerva-service.lcsb.uni.lu/plugins/guide/plugin.js'],
+  },
+  {
+    hash: 'b85ae2f4cd67736489b5fd2b635b1013',
+    name: 'Map exploation',
+    version: '1.0.0',
+    isPublic: true,
+    isDefault: false,
+    urls: ['https://minerva-service.lcsb.uni.lu/plugins/exploration/plugin.js'],
+  },
+  {
+    hash: '77c32edf387652dfaad8a20f2a0ce76b',
+    name: 'Drug reactions',
+    version: '1.0.0',
+    isPublic: true,
+    isDefault: false,
+    urls: ['https://minerva-service.lcsb.uni.lu/plugins/drug-reactions/plugin.js'],
+  },
+];
diff --git a/src/models/pluginSchema.ts b/src/models/pluginSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0204b6f05d9e797c3cbad124eb063222bcc3e6f3
--- /dev/null
+++ b/src/models/pluginSchema.ts
@@ -0,0 +1,10 @@
+import { z } from 'zod';
+
+export const pluginSchema = z.object({
+  hash: z.string(),
+  name: z.string(),
+  version: z.string(),
+  isPublic: z.boolean(),
+  isDefault: z.boolean(),
+  urls: z.array(z.string()),
+});
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index 212660e5ee66c695f389fd6c49b7168b6ec78ecb..0c592bc7c5b8895dde55a87d0b40051491f7c7f6 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -1,6 +1,6 @@
 import { PROJECT_ID } from '@/constants';
-import { PerfectSearchParams } from '@/types/search';
 import { Point } from '@/types/map';
+import { PerfectSearchParams } from '@/types/search';
 
 export const apiPath = {
   getBioEntityContentsStringWithQuery: ({
@@ -63,4 +63,5 @@ export const apiPath = {
   getSourceFile: (): string => `/projects/${PROJECT_ID}:downloadSource`,
   getMesh: (meshId: string): string => `mesh/${meshId}`,
   getTaxonomy: (taxonomyId: string): string => `taxonomy/${taxonomyId}`,
+  getAllPlugins: (): string => `/plugins/`,
 };
diff --git a/src/redux/plugins/plugins.constants.ts b/src/redux/plugins/plugins.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0aa77a3a906e4ecbfaf61cd980008a2a1ed7a397
--- /dev/null
+++ b/src/redux/plugins/plugins.constants.ts
@@ -0,0 +1,9 @@
+import { PluginsState } from './plugins.types';
+
+export const PLUGINS_INITIAL_STATE: PluginsState = {
+  list: {
+    data: [],
+    loading: 'idle',
+    error: { name: '', message: '' },
+  },
+};
diff --git a/src/redux/plugins/plugins.mock.ts b/src/redux/plugins/plugins.mock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2322bed65b3f54bb96ceb55ec122d73f93650654
--- /dev/null
+++ b/src/redux/plugins/plugins.mock.ts
@@ -0,0 +1,12 @@
+import { DEFAULT_ERROR } from '@/constants/errors';
+import { PluginsList, PluginsState } from './plugins.types';
+
+export const PLUGINS_INITIAL_STATE_LIST_MOCK: PluginsList = {
+  data: undefined,
+  loading: 'idle',
+  error: DEFAULT_ERROR,
+};
+
+export const PLUGINS_INITIAL_STATE_MOCK: PluginsState = {
+  list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+};
diff --git a/src/redux/plugins/plugins.reducers.ts b/src/redux/plugins/plugins.reducers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dd5f9fc6614702add5c78b11ccbf1811ad4bab65
--- /dev/null
+++ b/src/redux/plugins/plugins.reducers.ts
@@ -0,0 +1,17 @@
+import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
+import { getAllPlugins } from './plugins.thunks';
+import { PluginsState } from './plugins.types';
+
+export const getAllPluginsReducer = (builder: ActionReducerMapBuilder<PluginsState>): void => {
+  builder.addCase(getAllPlugins.pending, state => {
+    state.list.loading = 'pending';
+  });
+  builder.addCase(getAllPlugins.fulfilled, (state, action) => {
+    state.list.data = action.payload || [];
+    state.list.loading = 'succeeded';
+  });
+  builder.addCase(getAllPlugins.rejected, state => {
+    state.list.loading = 'failed';
+    // TODO to discuss manage state of failure
+  });
+};
diff --git a/src/redux/plugins/plugins.selectors.ts b/src/redux/plugins/plugins.selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5ece3dd2e529230dd8f85c413703675ebd7de90d
--- /dev/null
+++ b/src/redux/plugins/plugins.selectors.ts
@@ -0,0 +1,19 @@
+import { createSelector } from '@reduxjs/toolkit';
+import { rootSelector } from '../root/root.selectors';
+
+export const pluginsSelector = createSelector(rootSelector, state => state.plugins);
+
+export const pluginsListSelector = createSelector(pluginsSelector, plugins => {
+  return plugins.list;
+});
+
+export const pluginsListDataSelector = createSelector(pluginsListSelector, pluginsList => {
+  return pluginsList.data;
+});
+
+export const publicPluginsListSelector = createSelector(
+  pluginsListDataSelector,
+  pluginsListData => {
+    return (pluginsListData || []).filter(plugin => plugin.isPublic);
+  },
+);
diff --git a/src/redux/plugins/plugins.slice.ts b/src/redux/plugins/plugins.slice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8ac4e01130e47b994104373c7cfa0c41ad20b8ac
--- /dev/null
+++ b/src/redux/plugins/plugins.slice.ts
@@ -0,0 +1,14 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { PLUGINS_INITIAL_STATE } from './plugins.constants';
+import { getAllPluginsReducer } from './plugins.reducers';
+
+const pluginsState = createSlice({
+  name: 'plugins',
+  initialState: PLUGINS_INITIAL_STATE,
+  reducers: {},
+  extraReducers: builder => {
+    getAllPluginsReducer(builder);
+  },
+});
+
+export default pluginsState.reducer;
diff --git a/src/redux/plugins/plugins.thunks.ts b/src/redux/plugins/plugins.thunks.ts
new file mode 100644
index 0000000000000000000000000000000000000000..732cfdcb4fcadb1b83a804bb51c8f581d2269f50
--- /dev/null
+++ b/src/redux/plugins/plugins.thunks.ts
@@ -0,0 +1,18 @@
+import { pluginSchema } from '@/models/pluginSchema';
+import { axiosInstance } from '@/services/api/utils/axiosInstance';
+import { MinervaPlugin } from '@/types/models';
+import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
+import { createAsyncThunk } from '@reduxjs/toolkit';
+import { z } from 'zod';
+import { apiPath } from '../apiPath';
+
+export const getAllPlugins = createAsyncThunk(
+  'plugins/getAllPlugins',
+  async (): Promise<MinervaPlugin[]> => {
+    const response = await axiosInstance.get<MinervaPlugin[]>(apiPath.getAllPlugins());
+
+    const isDataValid = validateDataUsingZodSchema(response.data, z.array(pluginSchema));
+
+    return isDataValid ? response.data : [];
+  },
+);
diff --git a/src/redux/plugins/plugins.types.ts b/src/redux/plugins/plugins.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c7d7ae4c3ffdcf7c5477ddcb3bfa0408e7c2be77
--- /dev/null
+++ b/src/redux/plugins/plugins.types.ts
@@ -0,0 +1,8 @@
+import { FetchDataState } from '@/types/fetchDataState';
+import { MinervaPlugin } from '@/types/models';
+
+export type PluginsList = FetchDataState<MinervaPlugin[]>;
+
+export type PluginsState = {
+  list: PluginsList;
+};
diff --git a/src/redux/root/init.thunks.ts b/src/redux/root/init.thunks.ts
index c4ac19274381cdffa49913eff2a4e40ed79960e7..f6e14e6a928ae7e738fc3a267c10cd7592813379 100644
--- a/src/redux/root/init.thunks.ts
+++ b/src/redux/root/init.thunks.ts
@@ -1,25 +1,26 @@
-import { openSearchDrawerWithSelectedTab } from '@/redux/drawer/drawer.slice';
-import { createAsyncThunk } from '@reduxjs/toolkit';
+import { getDefaultSearchTab } from '@/components/FunctionalArea/TopBar/SearchBar/SearchBar.utils';
 import { PROJECT_ID } from '@/constants';
+import { openSearchDrawerWithSelectedTab } from '@/redux/drawer/drawer.slice';
 import { AppDispatch } from '@/redux/store';
 import { QueryData } from '@/types/query';
-import { getDefaultSearchTab } from '@/components/FunctionalArea/TopBar/SearchBar/SearchBar.utils';
+import { createAsyncThunk } from '@reduxjs/toolkit';
 import { getAllBackgroundsByProjectId } from '../backgrounds/backgrounds.thunks';
-import { getAllPublicOverlaysByProjectId } from '../overlays/overlays.thunks';
-import { getModels } from '../models/models.thunks';
-import { getProjectById } from '../project/project.thunks';
+import { getConfiguration, getConfigurationOptions } from '../configuration/configuration.thunks';
 import {
   initMapBackground,
   initMapPosition,
   initMapSizeAndModelId,
   initOpenedMaps,
 } from '../map/map.thunks';
-import { getSearchData } from '../search/search.thunks';
-import { setPerfectMatch } from '../search/search.slice';
-import { getSessionValid } from '../user/user.thunks';
+import { getModels } from '../models/models.thunks';
 import { getInitOverlays } from '../overlayBioEntity/overlayBioEntity.thunk';
-import { getConfiguration, getConfigurationOptions } from '../configuration/configuration.thunks';
+import { getAllPublicOverlaysByProjectId } from '../overlays/overlays.thunks';
+import { getAllPlugins } from '../plugins/plugins.thunks';
+import { getProjectById } from '../project/project.thunks';
+import { setPerfectMatch } from '../search/search.slice';
+import { getSearchData } from '../search/search.thunks';
 import { getStatisticsById } from '../statistics/statistics.thunks';
+import { getSessionValid } from '../user/user.thunks';
 
 interface InitializeAppParams {
   queryData: QueryData;
@@ -54,6 +55,9 @@ export const fetchInitialAppData = createAsyncThunk<
   dispatch(getStatisticsById(PROJECT_ID));
   dispatch(getConfiguration());
 
+  // Fetch plugins list
+  dispatch(getAllPlugins());
+
   /** Trigger search */
   if (queryData.searchValue) {
     dispatch(setPerfectMatch(queryData.perfectMatch));
diff --git a/src/redux/root/root.fixtures.ts b/src/redux/root/root.fixtures.ts
index c236df284e59fbdba9e80a306213f18410e9cc67..8bfe3f1bcafc071a633a9da208708244fb101015 100644
--- a/src/redux/root/root.fixtures.ts
+++ b/src/redux/root/root.fixtures.ts
@@ -1,25 +1,26 @@
 import { BACKGROUND_INITIAL_STATE_MOCK } from '../backgrounds/background.mock';
 import { BIOENTITY_INITIAL_STATE_MOCK } from '../bioEntity/bioEntity.mock';
 import { CHEMICALS_INITIAL_STATE_MOCK } from '../chemicals/chemicals.mock';
+import { COMPARTMENT_PATHWAYS_INITIAL_STATE_MOCK } from '../compartmentPathways/compartmentPathways.mock';
 import { CONFIGURATION_INITIAL_STATE } from '../configuration/configuration.adapter';
 import { CONTEXT_MENU_INITIAL_STATE } from '../contextMenu/contextMenu.constants';
 import { COOKIE_BANNER_INITIAL_STATE_MOCK } from '../cookieBanner/cookieBanner.mock';
 import { initialStateFixture as drawerInitialStateMock } from '../drawer/drawerFixture';
 import { DRUGS_INITIAL_STATE_MOCK } from '../drugs/drugs.mock';
+import { EXPORT_INITIAL_STATE_MOCK } from '../export/export.mock';
 import { LEGEND_INITIAL_STATE_MOCK } from '../legend/legend.mock';
 import { initialMapStateFixture } from '../map/map.fixtures';
 import { MODAL_INITIAL_STATE_MOCK } from '../modal/modal.mock';
 import { MODELS_INITIAL_STATE_MOCK } from '../models/models.mock';
 import { OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK } from '../overlayBioEntity/overlayBioEntity.mock';
 import { OVERLAYS_INITIAL_STATE_MOCK } from '../overlays/overlays.mock';
+import { PLUGINS_INITIAL_STATE_MOCK } from '../plugins/plugins.mock';
 import { PROJECT_STATE_INITIAL_MOCK } from '../project/project.mock';
 import { REACTIONS_STATE_INITIAL_MOCK } from '../reactions/reactions.mock';
 import { SEARCH_STATE_INITIAL_MOCK } from '../search/search.mock';
+import { STATISTICS_STATE_INITIAL_MOCK } from '../statistics/statistics.mock';
 import { RootState } from '../store';
 import { USER_INITIAL_STATE_MOCK } from '../user/user.mock';
-import { STATISTICS_STATE_INITIAL_MOCK } from '../statistics/statistics.mock';
-import { COMPARTMENT_PATHWAYS_INITIAL_STATE_MOCK } from '../compartmentPathways/compartmentPathways.mock';
-import { EXPORT_INITIAL_STATE_MOCK } from '../export/export.mock';
 
 export const INITIAL_STORE_STATE_MOCK: RootState = {
   search: SEARCH_STATE_INITIAL_MOCK,
@@ -43,4 +44,5 @@ export const INITIAL_STORE_STATE_MOCK: RootState = {
   statistics: STATISTICS_STATE_INITIAL_MOCK,
   compartmentPathways: COMPARTMENT_PATHWAYS_INITIAL_STATE_MOCK,
   export: EXPORT_INITIAL_STATE_MOCK,
+  plugins: PLUGINS_INITIAL_STATE_MOCK,
 };
diff --git a/src/redux/store.ts b/src/redux/store.ts
index a945a7518a65a15740f4922027fc4eb864b3d1cd..4e7447eba76d7e6d33cb5f70ffc8fc9b096ade8a 100644
--- a/src/redux/store.ts
+++ b/src/redux/store.ts
@@ -22,11 +22,12 @@ import {
   TypedStartListening,
   configureStore,
 } from '@reduxjs/toolkit';
+import compartmentPathwaysReducer from './compartmentPathways/compartmentPathways.slice';
+import exportReducer from './export/export.slice';
 import legendReducer from './legend/legend.slice';
 import { mapListenerMiddleware } from './map/middleware/map.middleware';
+import pluginsReducer from './plugins/plugins.slice';
 import statisticsReducer from './statistics/statistics.slice';
-import compartmentPathwaysReducer from './compartmentPathways/compartmentPathways.slice';
-import exportReducer from './export/export.slice';
 
 export const reducers = {
   search: searchReducer,
@@ -50,6 +51,7 @@ export const reducers = {
   statistics: statisticsReducer,
   compartmentPathways: compartmentPathwaysReducer,
   export: exportReducer,
+  plugins: pluginsReducer,
 };
 
 export const middlewares = [mapListenerMiddleware.middleware];
diff --git a/src/types/drawerName.ts b/src/types/drawerName.ts
index a5f3e3d2ff2f0155c67bdb1a458fc2ce64c5764f..3715c57ddd45995b4c8194a917bf0ad8a129b5f4 100644
--- a/src/types/drawerName.ts
+++ b/src/types/drawerName.ts
@@ -8,4 +8,5 @@ export type DrawerName =
   | 'submaps'
   | 'reaction'
   | 'overlays'
-  | 'bio-entity';
+  | 'bio-entity'
+  | 'available-plugins';
diff --git a/src/types/models.ts b/src/types/models.ts
index 437fa8d6655cbdc71ea1d9ec155d965a20fed0fa..293fd8ffe08e9930c8d2b88385a697b16834106e 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -37,6 +37,7 @@ import {
   overviewImageLinkModel,
 } from '@/models/overviewImageLink';
 import { overviewImageView } from '@/models/overviewImageView';
+import { pluginSchema } from '@/models/pluginSchema';
 import { projectSchema } from '@/models/projectSchema';
 import { reactionSchema } from '@/models/reaction';
 import { reactionLineSchema } from '@/models/reactionLineSchema';
@@ -88,3 +89,4 @@ export type CompartmentPathway = z.infer<typeof compartmentPathwaySchema>;
 export type CompartmentPathwayDetails = z.infer<typeof compartmentPathwayDetailsSchema>;
 export type ExportNetwork = z.infer<typeof exportNetworkchema>;
 export type ExportElements = z.infer<typeof exportElementsSchema>;
+export type MinervaPlugin = z.infer<typeof pluginSchema>; // Plugin type interfers with global Plugin type