diff --git a/src/commands/list.cpp b/src/commands/list.cpp
index 34057c6..64b0684 100644
--- a/src/commands/list.cpp
+++ b/src/commands/list.cpp
@@ -17,6 +17,8 @@
 namespace dropshell {
 
 int list_handler(const CommandContext& ctx);
+void show_server_details(const std::string& server_name);
+void list_servers();
 
 static std::vector<std::string> list_name_list={"list","ls","info","-l"};
 
@@ -53,6 +55,11 @@ int list_handler(const CommandContext& ctx) {
         return 0;
     }
 
+    if (ctx.args.size() == 1) {
+        show_server_details(ctx.args[0]);
+        return 0;
+    }
+
     std::cout << "List handler called with " << ctx.args.size() << " args\n";
     return 0;
 }
@@ -101,4 +108,76 @@ void list_servers() {
 }
 
 
+
+
+void show_server_details(const std::string& server_name) {
+    server_env_manager env(server_name);
+    if (!env.is_valid()) {
+        std::cerr << "Error: Invalid server environment file: " << server_name << std::endl;
+        return;
+    }
+
+    //---------------------
+    // Check if server is reachable via SSH
+    std::string ssh_address = env.get_SSH_HOST();
+    std::string ssh_user = env.get_SSH_USER();
+    std::string ssh_port = env.get_SSH_PORT();
+    if (!ssh_address.empty()) {
+        std::cout << std::endl << "Server Status:" << std::endl;
+        std::cout << std::string(40, '-') << std::endl;
+        
+        // Try to connect to the server
+        std::string cmd = "ssh -o ConnectTimeout=5 " + ssh_user + "@" + ssh_address + " -p " + ssh_port + " 'echo connected' 2>/dev/null";
+        int result = system(cmd.c_str());
+        if (result == 0) {
+            std::cout << "Status: Online" << std::endl;
+            
+            // // Get uptime if possible
+            // cmd = "ssh " + ssh_address + " 'uptime' 2>/dev/null";
+            // int rval = system(cmd.c_str());
+            // if (rval != 0) {
+            //     std::cout << "Error: Failed to get uptime" << std::endl;
+            // } 
+        } else {
+            std::cout << "Status: Offline" << std::endl;
+        }
+    }
+    std::cout << std::endl;
+
+    //---------------------
+    {
+        std::cout << std::endl;
+        tableprint tp("Server Configuration: " + server_name, true);
+        tp.add_row({"Key", "Value"});
+        for (const auto& [key, value] : env.get_variables()) {
+            tp.add_row({key, value});
+        }
+        tp.print();
+    }
+
+    //---------------------
+    // list services, and run healthcheck on each
+    {
+        tableprint tp("Services: " + server_name, false);
+        tp.add_row({"Status", "Service", "Ports"});
+        
+
+        std::map<std::string, ServiceStatus> status = service_runner::get_all_services_status(server_name); 
+
+        std::set<int> ports_used;
+        std::string serviceticks = "";
+        for (const auto& [service_name, service_status] : status) {
+            std::string healthy = service_runner::HealthStatus2String(service_status.health);
+            
+            std::string ports_str = "";
+            for (const auto& port : service_status.ports) 
+                ports_str += std::to_string(port) + " ";
+        
+            tp.add_row({healthy, service_name, ports_str});
+        } // end of for (const auto& service : services)
+        tp.print();
+    } // end of list services
+} // end of show_server_details
+
+
 } // namespace dropshell
\ No newline at end of file
diff --git a/src/commands/nuke.cpp b/src/commands/nuke.cpp
new file mode 100644
index 0000000..1426e4f
--- /dev/null
+++ b/src/commands/nuke.cpp
@@ -0,0 +1,96 @@
+#include "command_registry.hpp"
+#include "shared_commands.hpp"
+#include "config.hpp"
+#include "services.hpp"
+#include "server_env_manager.hpp"
+#include "utils/directories.hpp"
+#include "servers.hpp"
+#include "templates.hpp"
+
+#include <libassert/assert.hpp>
+
+namespace dropshell {
+
+int nuke_handler(const CommandContext& ctx);
+static std::vector<std::string> nuke_name_list={"nuke"};
+
+// Static registration
+struct NukeCommandRegister {
+    NukeCommandRegister() {
+        CommandRegistry::instance().register_command({
+            nuke_name_list,
+            nuke_handler,
+            std_autocomplete,
+            false, // hidden
+            true, // requires_config
+            2,     // min_args (after command)
+            2,     // max_args (after command)
+            "nuke SERVER SERVICE",
+            "Nuke a service on a server. Destroys everything, both local and remote!",
+            // heredoc
+            R"(
+            Nuke a service on a server. Destroys everything, both local and remote!
+            nuke <server> <service>    nuke the given service on the given server.
+            )"
+        });
+    }
+} nuke_command_register;
+
+int nuke_handler(const CommandContext &ctx)
+{
+    ASSERT(ctx.args.size() > 1, "Usage: nuke <server> <service>");
+    ASSERT(gConfig().is_config_set(), "No configuration found. Please run 'dropshell config' to set up your configuration.");
+
+    std::string server = safearg(ctx.args, 0);
+    std::string service = safearg(ctx.args, 1);
+
+    maketitle("Nuking " + service + " on " + server);
+
+    server_env_manager server_env(server);
+    LocalServiceInfo service_info;
+
+    if (server_env.is_valid())
+    {
+        service_info = get_service_info(server, service);
+        if (!SIvalid(service_info))
+            std::cerr << "Warning: Invalid service: " << service << std::endl;
+        else
+            if (!uninstall_service(server, service, false))
+                std::cerr << "Warning: Failed to uninstall service: " << service << std::endl;
+
+        // run the nuke script on the remote server if it exists.
+        if (gTemplateManager().template_command_exists(service_info.template_name, "nuke"))
+        {
+            if (!server_env.run_remote_template_command(service, "nuke", {}, false, {}))
+                std::cerr << "Warning: Failed to run nuke script: " << service << std::endl;
+        }
+
+        // remove the remote service directory, running in a docker container as root.
+        std::string rm_cmd = "docker run --rm -v " + quote(remotepath::service(server, service)) + ":/service alpine rm -rf /service";
+        if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent))
+        {
+            std::cerr << "Warning: Failed to remove remote service directory" << std::endl;
+            std::cerr << "You may need to log in and delete it manually." << std::endl;
+            std::cerr << "   ssh " << server << std::endl;
+            std::cerr << "   rm -rf " << remotepath::service(server, service) << std::endl;
+        }
+    }
+    else
+        std::cerr << "Warning: Invalid server: " << server << std::endl;
+
+    // remove the local service directory
+    std::string local_service_path = service_info.local_service_path;
+    if (local_service_path.empty() || !std::filesystem::exists(local_service_path))
+    {
+        std::cerr << "Warning: Local service directory not found: " << local_service_path << std::endl;
+        return 1;
+    }
+
+    auto ret = std::filesystem::remove_all(local_service_path);
+    if (ret != 0)
+        std::cerr << "Warning: Failed to remove local service directory" << std::endl;
+
+    return ret == 0 ? 0 : 1;
+}
+
+} // namespace dropshell
\ No newline at end of file
diff --git a/src/commands/shared_commands.hpp b/src/commands/shared_commands.hpp
index d07dc6a..4e71c91 100644
--- a/src/commands/shared_commands.hpp
+++ b/src/commands/shared_commands.hpp
@@ -15,6 +15,7 @@ namespace dropshell {
 
     // defined in install.cpp
     bool install_service(const std::string& server, const std::string& service, bool silent);
+    bool uninstall_service(const std::string& server, const std::string& service, bool silent);
 
     // defined in health.cpp
     std::string healthtick(const std::string& server, const std::string& service);
diff --git a/src/commands/uninstall.cpp b/src/commands/uninstall.cpp
new file mode 100644
index 0000000..7f09731
--- /dev/null
+++ b/src/commands/uninstall.cpp
@@ -0,0 +1,109 @@
+#include "command_registry.hpp"
+#include "directories.hpp"
+#include "shared_commands.hpp"
+
+namespace dropshell
+{
+
+    int uninstall_handler(const CommandContext &ctx);
+
+    static std::vector<std::string> uninstall_name_list = {"uninstall", "remove"};
+
+    // Static registration
+    struct UninstallCommandRegister
+    {
+        UninstallCommandRegister()
+        {
+            CommandRegistry::instance().register_command({uninstall_name_list,
+                                                          uninstall_handler,
+                                                          std_autocomplete,
+                                                          false, // hidden
+                                                          false, // requires_config
+                                                          1,     // min_args (after command)
+                                                          2,     // max_args (after command)
+                                                          "uninstall SERVER [SERVICE]",
+                                                          "Uninstall a service on a server. Does not remove configuration or user data.",
+                                                          // heredoc
+                                                          R"(
+                Uninstall a service on a server. Does not remove configuration or user data.
+                uninstall <server> <service>    uninstall the given service on the given server.
+                uninstall <server>              uninstall all services on the given server.
+                )"});
+        }
+    } uninstall_command_register;
+
+    int uninstall_handler(const CommandContext &ctx)
+    {
+        if (ctx.args.size() < 1)
+        {
+            std::cerr << "Error: uninstall requires a server and (optionally) a service" << std::endl;
+            return 1;
+        }
+
+        std::string server = safearg(ctx.args, 0);
+
+        if (ctx.args.size() == 1)
+        {
+            // uninstall all services on the server
+            bool okay = true;
+            std::vector<LocalServiceInfo> services = get_server_services_info(server);
+            for (const auto &service : services)
+            {
+                if (!uninstall_service(server, service.service_name, false))
+                    okay = false;
+            }
+            return okay ? 0 : 1;
+        }
+
+        std::string service = safearg(ctx.args, 1);
+        return uninstall_service(server, service, false) ? 0 : 1;
+    }
+
+    bool uninstall_service(const std::string &server, const std::string &service, bool silent)
+    {
+        if (!silent)
+            maketitle("Uninstalling " + service + " on " + server);
+
+        server_env_manager server_env(server);
+        if (!server_env.is_valid())
+        {
+            std::cerr << "Invalid server: " << server << std::endl;
+            return false; // should never hit this.
+        }
+
+        // 2. Check if service directory exists on server
+        if (!server_env.check_remote_dir_exists(remotepath::service(server, service)))
+        {
+            std::cerr << "Service is not installed: " << service << std::endl;
+            return true; // Nothing to uninstall
+        }
+
+        // 3. Run uninstall script if it exists
+        std::string uninstall_script = remotepath::service_template(server, service) + "/uninstall.sh";
+        bool script_exists = server_env.check_remote_file_exists(uninstall_script);
+
+        if (script_exists)
+        {
+            if (!server_env.run_remote_template_command(service, "uninstall", {}, silent, {}))
+                if (!silent)
+                    std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl;
+        }
+        else
+            if (!silent)
+                std::cerr << "Warning: No uninstall script found, continuing with direcotry removal." << std::endl;
+    
+        // 4. Remove the service directory from the server
+        std::string rm_cmd = "rm -rf " + quote(remotepath::service(server, service));
+        if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent))
+        {
+            if (!silent)
+                std::cerr << "Failed to remove service directory" << std::endl;
+            return false;
+        }
+
+        if (!silent)
+            std::cout << "Service " << service << " successfully uninstalled from " << server << std::endl;
+        return true;
+    }
+
+} // namespace dropshell
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 668ee6e..d29ff02 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -158,14 +158,6 @@ int old_main(int argc, char* argv[]) {
 
         std::string cmd = argv[1];
 
-        if (cmd == "autocomplete")
-        {
-            std::vector<std::string> argvec;
-            for (int i = 0; i < argc; i++)
-                argvec.push_back(argv[i]);
-            return autocomplete::autocomplete(argvec) ? 0 : 1;
-        }
-
 
         // ------------------------------------------------------------
         // from here we require the config file to be loaded.
@@ -183,22 +175,6 @@ int old_main(int argc, char* argv[]) {
         if (gTemplateManager().is_loaded() && gTemplateManager().get_source_count() > 0)
             gTemplateManager().print_sources();
 
-        if (cmd == "server" || cmd == "servers" || cmd == "list" || cmd == "view") 
-            switch (argc)
-            {
-                case 2:
-                    list_servers();
-                    return 0;
-                case 3:
-                    show_server_details(argv[2]);
-                    return 0;
-                case 4:
-                    cmd="logs";
-                    break;
-                default:
-                    return die("dropshell server: too many arguments");
-            }
-
         HAPPYEXIT("templates", gTemplateManager().list_templates());
 
         if (cmd == "create-template") {
diff --git a/src/servers.cpp b/src/servers.cpp
index c477d65..5564bfc 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -72,75 +72,6 @@ ServerInfo get_server_info(const std::string &server_name)
 }
 
 
-void show_server_details(const std::string& server_name) {
-    server_env_manager env(server_name);
-    if (!env.is_valid()) {
-        std::cerr << "Error: Invalid server environment file: " << server_name << std::endl;
-        return;
-    }
-
-    //---------------------
-    // Check if server is reachable via SSH
-    std::string ssh_address = env.get_SSH_HOST();
-    std::string ssh_user = env.get_SSH_USER();
-    std::string ssh_port = env.get_SSH_PORT();
-    if (!ssh_address.empty()) {
-        std::cout << std::endl << "Server Status:" << std::endl;
-        std::cout << std::string(40, '-') << std::endl;
-        
-        // Try to connect to the server
-        std::string cmd = "ssh -o ConnectTimeout=5 " + ssh_user + "@" + ssh_address + " -p " + ssh_port + " 'echo connected' 2>/dev/null";
-        int result = system(cmd.c_str());
-        if (result == 0) {
-            std::cout << "Status: Online" << std::endl;
-            
-            // // Get uptime if possible
-            // cmd = "ssh " + ssh_address + " 'uptime' 2>/dev/null";
-            // int rval = system(cmd.c_str());
-            // if (rval != 0) {
-            //     std::cout << "Error: Failed to get uptime" << std::endl;
-            // } 
-        } else {
-            std::cout << "Status: Offline" << std::endl;
-        }
-    }
-    std::cout << std::endl;
-
-    //---------------------
-    {
-        std::cout << std::endl;
-        tableprint tp("Server Configuration: " + server_name, true);
-        tp.add_row({"Key", "Value"});
-        for (const auto& [key, value] : env.get_variables()) {
-            tp.add_row({key, value});
-        }
-        tp.print();
-    }
-
-    //---------------------
-    // list services, and run healthcheck on each
-    {
-        tableprint tp("Services: " + server_name, false);
-        tp.add_row({"Status", "Service", "Ports"});
-        
-
-        std::map<std::string, ServiceStatus> status = service_runner::get_all_services_status(server_name); 
-
-        std::set<int> ports_used;
-        std::string serviceticks = "";
-        for (const auto& [service_name, service_status] : status) {
-            std::string healthy = service_runner::HealthStatus2String(service_status.health);
-            
-            std::string ports_str = "";
-            for (const auto& port : service_status.ports) 
-                ports_str += std::to_string(port) + " ";
-        
-            tp.add_row({healthy, service_name, ports_str});
-        } // end of for (const auto& service : services)
-        tp.print();
-    } // end of list services
-} // end of show_server_details
-
 bool create_server(const std::string &server_name)
 {
     // 1. check if server name already exists
diff --git a/src/servers.hpp b/src/servers.hpp
index 4afbf66..eb09849 100644
--- a/src/servers.hpp
+++ b/src/servers.hpp
@@ -20,10 +20,6 @@ namespace dropshell {
 
     ServerInfo get_server_info(const std::string& server_name);
 
-
-    void list_servers();
-    void show_server_details(const std::string& server_name);
-
     bool create_server(const std::string& server_name);
    
     void get_all_used_commands(std::set<std::string> &commands);