diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs
index 0736c4ed..925f9ddc 100644
--- a/Application/ApplicationManager.cs
+++ b/Application/ApplicationManager.cs
@@ -15,6 +15,7 @@ using System;
 using System.Collections;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Collections.Immutable;
 using System.Linq;
 using System.Reflection;
 using System.Text;
@@ -217,6 +218,8 @@ namespace IW4MAdmin.Application
             return _commands;
         }
 
+        public IReadOnlyList<IManagerCommand> Commands => _commands.ToImmutableList();
+
         public async Task UpdateServerStates()
         {
             // store the server hash code and task for it
diff --git a/Application/Commands/HelpCommand.cs b/Application/Commands/HelpCommand.cs
new file mode 100644
index 00000000..c0b6201a
--- /dev/null
+++ b/Application/Commands/HelpCommand.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Data.Models.Client;
+using SharedLibraryCore;
+using SharedLibraryCore.Commands;
+using SharedLibraryCore.Configuration;
+using SharedLibraryCore.Interfaces;
+
+namespace IW4MAdmin.Application.Commands
+{
+    /// <summary>
+    /// Prints help information
+    /// </summary>
+    public class HelpCommand : Command
+    {
+        public HelpCommand(CommandConfiguration config, ITranslationLookup translationLookup) :
+            base(config, translationLookup)
+        {
+            Name = "help";
+            Description = translationLookup["COMMANDS_HELP_DESC"];
+            Alias = "h";
+            Permission = EFClient.Permission.User;
+            RequiresTarget = false;
+            Arguments = new[]
+            {
+                new CommandArgument
+                {
+                    Name = translationLookup["COMMANDS_ARGS_COMMANDS"],
+                    Required = false
+                }
+            };
+        }
+
+        public override Task ExecuteAsync(GameEvent gameEvent)
+        {
+            var searchTerm = gameEvent.Data.Trim();
+            var availableCommands = gameEvent.Owner.Manager.Commands.Distinct().Where(command =>
+                    command.SupportedGames == null || !command.SupportedGames.Any() ||
+                    command.SupportedGames.Contains(gameEvent.Owner.GameName))
+                .Where(command => gameEvent.Origin.Level >= command.Permission);
+
+            if (searchTerm.Length > 2)
+            {
+                var matchingCommand = availableCommands.FirstOrDefault(command =>
+                    command.Name.Equals(searchTerm, StringComparison.InvariantCultureIgnoreCase) ||
+                    command.Alias.Equals(searchTerm, StringComparison.InvariantCultureIgnoreCase));
+
+                if (matchingCommand != null)
+                {
+                    gameEvent.Origin.Tell(_translationLookup["COMMANDS_HELP_SEARCH_RESULT"]
+                        .FormatExt(matchingCommand.Name, matchingCommand.Alias));
+                    gameEvent.Origin.Tell(matchingCommand.Syntax);
+                }
+
+                else
+                {
+                    gameEvent.Origin.Tell(_translationLookup["COMMANDS_HELP_NOTFOUND"]);
+                }
+            }
+
+            else
+            {
+                var commandStrings = availableCommands.Select((command, index) =>
+                    new
+                    {
+                        response = $" {_translationLookup["COMMANDS_HELP_LIST_FORMAT"].FormatExt(command.Name)} ",
+                        index
+                    });
+
+                var helpResponse = new StringBuilder();
+
+                foreach (var item in commandStrings)
+                {
+                    helpResponse.Append(item.response);
+                    if (item.index == 0 || item.index % 4 != 0)
+                    {
+                        continue;
+                    }
+
+                    gameEvent.Origin.Tell(helpResponse.ToString());
+                    helpResponse = new StringBuilder();
+                }
+
+                gameEvent.Origin.Tell(helpResponse.ToString());
+                gameEvent.Origin.Tell(_translationLookup["COMMANDS_HELP_MOREINFO"]);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+}
\ No newline at end of file
diff --git a/SharedLibraryCore/Command.cs b/SharedLibraryCore/Command.cs
index 7f61bd11..bdbce022 100644
--- a/SharedLibraryCore/Command.cs
+++ b/SharedLibraryCore/Command.cs
@@ -23,6 +23,7 @@ namespace SharedLibraryCore
         {
             _config = config;
             _translationLookup = layout;
+            SupportedGames = new Game[0];
         }
 
         /// <summary>
diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs
index 03ed5aec..6a4a7618 100644
--- a/SharedLibraryCore/Commands/NativeCommands.cs
+++ b/SharedLibraryCore/Commands/NativeCommands.cs
@@ -503,80 +503,6 @@ namespace SharedLibraryCore.Commands
         }
     }
 
-    /// <summary>
-    /// Prints help information
-    /// </summary>
-    public class HelpCommand : Command
-    {
-        public HelpCommand(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
-        {
-            Name = "help";
-            Description = _translationLookup["COMMANDS_HELP_DESC"];
-            Alias = "h";
-            Permission = Permission.User;
-            RequiresTarget = false;
-            Arguments = new[]
-            {
-                new CommandArgument()
-                {
-                    Name = _translationLookup["COMMANDS_ARGS_COMMANDS"],
-                    Required = false
-                }
-            };
-        }
-
-        public override Task ExecuteAsync(GameEvent E)
-        {
-            string cmd = E.Data.Trim();
-
-            if (cmd.Length > 2)
-            {
-                bool found = false;
-                foreach (var command in E.Owner.Manager.GetCommands())
-                {
-                    if (command.Name == cmd.ToLower() ||
-                        command.Alias == cmd.ToLower())
-                    {
-                        E.Origin.Tell($"[^3{command.Name}^7] {command.Description}");
-                        E.Origin.Tell(command.Syntax);
-                        found = true;
-                    }
-                }
-
-                if (!found)
-                {
-                    E.Origin.Tell(_translationLookup["COMMANDS_HELP_NOTFOUND"]);
-                }
-            }
-
-            else
-            {
-                int count = 0;
-                StringBuilder helpResponse = new StringBuilder();
-                var CommandList = E.Owner.Manager.GetCommands();
-
-                foreach (Command C in CommandList)
-                {
-                    if (E.Origin.Level >= C.Permission)
-                    {
-                        helpResponse.Append(" [^3" + C.Name + "^7] ");
-                        if (count >= 4)
-                        {
-                            E.Origin.Tell(helpResponse.ToString());
-                            helpResponse = new StringBuilder();
-                            count = 0;
-                        }
-                        count++;
-                    }
-                }
-                E.Origin.Tell(helpResponse.ToString());
-                E.Origin.Tell(_translationLookup["COMMANDS_HELP_MOREINFO"]);
-            }
-
-            return Task.CompletedTask;
-        }
-    }
-
     /// <summary>
     /// Fast restarts the map
     /// </summary>
diff --git a/SharedLibraryCore/Interfaces/IManager.cs b/SharedLibraryCore/Interfaces/IManager.cs
index a8260108..f4c8bcf4 100644
--- a/SharedLibraryCore/Interfaces/IManager.cs
+++ b/SharedLibraryCore/Interfaces/IManager.cs
@@ -20,6 +20,7 @@ namespace SharedLibraryCore.Interfaces
         ILogger GetLogger(long serverId);
         IList<Server> GetServers();
         IList<IManagerCommand> GetCommands();
+        IReadOnlyList<IManagerCommand> Commands { get; }
         IList<Helpers.MessageToken> GetMessageTokens();
         IList<EFClient> GetActiveClients();
         EFClient FindActiveClient(EFClient client);