diff --git a/src/main.cpp b/src/main.cpp
index d2a4d73..0d2c587 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -8,7 +8,6 @@
 #include "utils/utils.hpp"
 #include "utils/readmes.hpp"
 #include "autocomplete.hpp"
-#include "main_commands.hpp"
 #include "utils/hash.hpp"
 
 #include <filesystem>
@@ -69,17 +68,55 @@ int die(const std::string & msg) {
     return 1;
 }
 
-bool parseargs(std::string arg2, std::string arg3, std::string & server_name, std::vector<LocalServiceInfo>& servicelist)
+int init(const std::vector<std::string> &args)
+{
+    std::string lcd;
+
+    if (args.size() < 3) {
+        std::cerr << "Error: init command requires a directory argument" << std::endl;
+        return 1;
+    }
+    try {
+        if (!gConfig().add_local_config_directory(args[2])) 
+            return 1; // error already reported
+
+        gConfig().save_config();
+        std::cout << "Config directory added: " << gConfig().get_local_config_directories().back() << std::endl;
+        dropshell::create_readme_local_config_dir(gConfig().get_local_config_directories().back());
+        
+        if (gConfig().get_local_config_directories().size() ==1)
+            std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server <server-name>'" << std::endl;
+        else
+        {
+            std::cout << "DropShell will now use all of the following directories for configuration:" << std::endl;
+            for (const auto& dir : gConfig().get_local_config_directories()) {
+                std::cout << "  " << dir << std::endl;
+            }
+            std::cout << "You can edit the config file manually with:   dropshell edit" << std::endl;
+        }
+    } catch (const std::exception& e) {
+        std::cerr << "Error in init: " << e.what() << std::endl;
+        return 1;
+    }
+    return 0;
+}
+
+struct ServerAndServices {
+    std::string server_name;
+    std::vector<LocalServiceInfo> servicelist;
+};
+
+bool getCLIServices(const std::string & arg2, const std::string & arg3, 
+    ServerAndServices & server_and_services)
 {
     if (arg2.empty()) return false;
-    server_name = arg2;
+    server_and_services.server_name = arg2;
 
     if (arg3.empty()) {
-        servicelist = get_server_services_info(server_name);
+        server_and_services.servicelist = get_server_services_info(arg2);
     } else {
-        servicelist.push_back(get_service_info(server_name, arg3));
+        server_and_services.servicelist.push_back(get_service_info(arg2, arg3));
     }
-
     return true;
 }
 
@@ -126,7 +163,7 @@ int main(int argc, char* argv[]) {
         }
 
         if (cmd == "init") {
-            return main_commands::init(argvec);
+            return init(argvec);
         }
 
         if (cmd == "help" || cmd == "-h" || cmd == "--help" || cmd== "h" || cmd=="halp") {
@@ -203,36 +240,28 @@ int main(int argc, char* argv[]) {
             return 0;
         }
 
-        if (cmd == "backup" || cmd=="backups") {
-            if (argc < 4) return die("Error: backup requires a target server and target service to back up");
-            return main_commands::backup(argvec);
-        }
-
-        if (cmd == "restore") {
-            if (argc < 4) return die("Error: restore requires a target server, target service the backup file to restore");
-            return main_commands::restore(argvec);
-        }
-
         // handle running a command. 
         std::set<std::string> commands;
         get_all_used_commands(commands);
         commands.merge(std::set<std::string>{"ssh","edit","_allservicesstatus"}); // handled by service_runner, but not in template_shell_commands.
         for (const auto& command : commands) {
             if (cmd == command) {
-                std::string server_name;
-                std::vector<LocalServiceInfo> servicelist;
-                if (!parseargs(safearg(argc, argv, 2), safearg(argc, argv, 3), server_name, servicelist)) {
+                ServerAndServices server_and_services;
+                if (!getCLIServices(safearg(argc, argv, 2), safearg(argc, argv, 3), server_and_services)) {
                     std::cerr << "Error: " << command << " command requires server name and optionally service name" << std::endl;
                     return 1;
                 }
 
-                for (const auto& service_info : servicelist) {
-                    service_runner runner(server_name, service_info.service_name);
+                for (const auto& service_info : server_and_services.servicelist) {
+                    service_runner runner(server_and_services.server_name, service_info.service_name);
                     if (!runner.isValid()) {
                         std::cerr << "Error: Failed to initialize service" << std::endl;
                         return 1;
                     }
-                    if (!runner.run_command(command)) {
+                    std::vector<std::string> additional_args;
+                    for (int i=4; i<argc; i++)
+                        additional_args.push_back(argv[i]);
+                    if (!runner.run_command(command, additional_args)) {
                         std::cerr << command +" failed." << std::endl;
                         return 1;
                     }
diff --git a/src/main_commands.cpp b/src/main_commands.cpp
deleted file mode 100644
index a543072..0000000
--- a/src/main_commands.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-#include "main_commands.hpp"
-
-#include "utils/directories.hpp"
-#include "utils/utils.hpp"
-#include "utils/readmes.hpp"
-#include "service_runner.hpp"
-#include "config.hpp"
-#include "templates.hpp"
-#include "server_env_manager.hpp"
-
-#include <iostream>
-#include <filesystem>
-#include <algorithm>
-
-namespace dropshell {
-
-namespace main_commands {
-
-
-static const std::string magic_string = "-_-";
-
-
-int init(const std::vector<std::string> &args)
-{
-    std::string lcd;
-
-    if (args.size() < 3) {
-        std::cerr << "Error: init command requires a directory argument" << std::endl;
-        return 1;
-    }
-    try {
-        if (!gConfig().add_local_config_directory(args[2])) 
-            return 1; // error already reported
-
-        gConfig().save_config();
-        std::cout << "Config directory added: " << gConfig().get_local_config_directories().back() << std::endl;
-        dropshell::create_readme_local_config_dir(gConfig().get_local_config_directories().back());
-        
-        if (gConfig().get_local_config_directories().size() ==1)
-            std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server <server-name>'" << std::endl;
-        else
-        {
-            std::cout << "DropShell will now use all of the following directories for configuration:" << std::endl;
-            for (const auto& dir : gConfig().get_local_config_directories()) {
-                std::cout << "  " << dir << std::endl;
-            }
-            std::cout << "You can edit the config file manually with:   dropshell edit" << std::endl;
-        }
-    } catch (const std::exception& e) {
-        std::cerr << "Error in init: " << e.what() << std::endl;
-        return 1;
-    }
-    return 0;
-}
-
-int restore(const std::vector<std::string> &args, bool silent)
-{
-    if (args.size() < 4) {
-        std::cerr << "Error: not enough arguments.  dropshell restore <server> <service> <backup-file>" << std::endl;
-        return 1;
-    }
-
-    std::string server_name = args[2];
-    std::string service_name = args[3];
-    std::string backup_file = args[4];
-
-    auto service_info = get_service_info(server_name, service_name);
-    if (service_info.local_service_path.empty()) {
-        std::cerr << "Error: Service not found" << std::endl;
-        return 1;
-    }
-
-    server_env_manager env(server_name);
-    if (!env.is_valid()) {
-        std::cerr << "Error: Invalid server environment" << std::endl;
-        return 1;
-    }
-
-    std::string local_backups_dir = localpath::backups_path();
-    std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string();
-
-    if (! std::filesystem::exists(local_backup_file_path)) {
-        std::cerr << "Error: Backup file not found at " << local_backup_file_path << std::endl;
-        return 1;
-    }
-
-    // split the backup filename into parts based on the magic string
-    std::vector<std::string> parts = dropshell::split(backup_file, magic_string);
-    if (parts.size() != 4) {
-        std::cerr << "Error: Backup file format is incompatible, - in one of the names?" << std::endl;
-        return 1;
-    }
-
-    std::string backup_server_name = parts[0];
-    std::string backup_template_name = parts[1];
-    std::string backup_service_name = parts[2];
-    std::string backup_datetime = parts[3];
-
-    if (backup_template_name != service_info.template_name) {
-        std::cerr << "Error: Backup template does not match service template. Can't restore." << std::endl;
-        return 1;
-    }
-
-    std::string nicedate = std::string(backup_datetime).substr(0, 10);
-
-    std::cout << "Restoring " << nicedate << " backup of " << backup_template_name << " taken from "<<backup_server_name<<", onto "<<server_name<<std::endl;
-    std::cout << std::endl;
-    std::cout << "*** ALL DATA FOR "<<server_name<<"/"<<service_name<<" WILL BE OVERWRITTEN! ***"<<std::endl;
-    std::cout << std::endl;
-    std::cout << "Are you sure you want to continue? (y/n)" << std::endl;
-    char confirm;
-    std::cin >> confirm;
-    if (confirm != 'y') {
-        std::cout << "Restore cancelled." << std::endl;
-        return 1;
-    }
-
-    // run the restore script
-    std::cout << "OK, here goes..." << std::endl;
-
-    { // backup existing service
-        std::cout << "1) Backing up existing service... " << std::flush;
-        std::vector<std::string> backup_args = {"dropshell","backup",server_name, service_name};
-        if (!backup(backup_args,true)) // silent=true
-        {
-            std::cerr << std::endl;
-            std::cerr << "Error: Backup failed, restore aborted." << std::endl;
-            std::cerr << "You can try using   dropshell install "<<server_name<<" "<<service_name<<"   to install the service afresh." << std::endl;
-            std::cerr << "Otherwise, stop the service, create and initialise a new one, then restore to that." << std::endl;
-            return 1;
-        }
-        std::cout << "Backup complete." << std::endl;
-    }
-
-    { // restore service from backup
-        std::cout << "2) Restoring service from backup..." << std::endl;
-        std::string remote_backups_dir = remotepath::backups(server_name);
-        std::string remote_backup_file_path = remote_backups_dir + "/" + backup_file;
-
-        // Copy backup file from local to server
-        std::string scp_cmd = "scp -P " + env.get_SSH_PORT() + " " + quote(local_backup_file_path) + " " + env.get_SSH_USER() + "@" + env.get_SSH_HOST() + ":" + quote(remote_backup_file_path) + (silent ? " > /dev/null 2>&1" : "");
-        if (!env.execute_local_command(scp_cmd)) {
-            std::cerr << "Failed to copy backup file from server" << std::endl;
-            return false;
-        }
-        env.run_remote_template_command(service_name, "restore", {remote_backup_file_path}, silent);
-    }
-
-    // healthcheck the service
-    std::cout << "3) Healthchecking service..." << std::endl;
-    std::string green_tick = "\033[32m✓\033[0m";
-    std::string red_cross = "\033[31m✗\033[0m";    
-    bool healthy= (env.run_remote_template_command(service_name, "status", {}, silent));
-    if (!silent)
-        std::cout << (healthy ? green_tick : red_cross) << " Service is " << (healthy ? "healthy" : "NOT healthy") << std::endl;
-
-    return 0;
-}
-
-bool name_breaks_backups(std::string name)
-{
-    // if name contains -_-, return true
-    return name.find("-_-") != std::string::npos;
-}
-
-
-        // backup the service over ssh, using the credentials from server.env (via server_env.hpp)
-        // 1. run backup.sh on the server
-        // 2. create a backup file with format server-service-datetime.tgz
-        // 3. store it in the server's DROPSHELL_DIR/backups folder
-        // 4. copy it to the local user_dir/backups folder
-
-// ------------------------------------------------------------------------------------------------
-// Backup the service.
-// ------------------------------------------------------------------------------------------------
-int backup(const std::vector<std::string> & args, bool silent) {
-    if (args.size() < 4) {
-        std::cerr << "Error: backup command requires a server name and service name" << std::endl;
-        return 1;
-    }
-
-    std::string server_name = args[2];
-    std::string service_name = args[3];
-
-    auto service_info = get_service_info(server_name, service_name);
-    if (service_info.local_service_path.empty()) {
-        std::cerr << "Error: Service not found" << std::endl;
-        return 1;
-    }
-
-    server_env_manager env(server_name);
-    if (!env.is_valid()) {
-        std::cerr << "Error: Invalid server environment" << std::endl;
-        return 1;
-    }
-
-    const std::string command = "backup";
-
-    if (!template_command_exists(service_info.template_name, command)) {
-        std::cout << "No backup script for " << service_info.template_name << std::endl;
-        return true; // nothing to back up.
-    }
-    
-    // Check if basic installed stuff is in place.
-    std::string remote_service_template_path = remotepath::service_template(server_name, service_name);
-    std::string remote_command_script_file = remote_service_template_path + "/" + command + ".sh";
-    std::string remote_service_config_path = remotepath::service_config(server_name, service_name);
-    if (!env.check_remote_items_exist({
-        remotepath::service(server_name, service_name),
-        remote_command_script_file,
-        remotefile::service_env(server_name, service_name)})
-    )
-    {
-        std::cerr << "Error: Required service directories not found on remote server" << std::endl;
-        std::cerr << "Is the service installed?" << std::endl;
-        return false;
-    }
-
-    // Create backups directory on server if it doesn't exist
-    std::string remote_backups_dir = remotepath::backups(server_name);
-    if (!silent) std::cout << "Remote backups directory on "<< server_name <<": " << remote_backups_dir << std::endl;
-    std::string mkdir_cmd = "mkdir -p " + quote(remote_backups_dir);
-    if (!env.execute_ssh_command(mkdir_cmd)) {
-        std::cerr << "Failed to create backups directory on server" << std::endl;
-        return false;
-    }
-
-    // Create backups directory locally if it doesn't exist
-    std::string local_backups_dir = localpath::backups_path();
-    if (local_backups_dir.empty()) {
-        std::cerr << "Error: Local backups directory not found - is DropShell initialised?" << std::endl;
-        return false;
-    }
-    if (!std::filesystem::exists(local_backups_dir)) 
-        std::filesystem::create_directories(local_backups_dir);
-
-    // Get current datetime for backup filename
-    auto now = std::chrono::system_clock::now();
-    auto time = std::chrono::system_clock::to_time_t(now);
-    std::stringstream datetime;
-    datetime << std::put_time(std::localtime(&time), "%Y-%m-%d_%H-%M-%S");
-    
-    if (name_breaks_backups(server_name)) {std::cerr << "Error: Server name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
-    if (name_breaks_backups(service_name)) {std::cerr << "Error: Service name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
-    if (name_breaks_backups(service_info.template_name)) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
-
-    // Construct backup filename
-    std::string backup_filename = server_name + magic_string + service_info.template_name + magic_string + service_name + magic_string + datetime.str() + ".tgz";
-    std::string remote_backup_file_path = remote_backups_dir + "/" + backup_filename;
-    std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_filename).string();
-
-    // assert that the backup filename is valid - -_- appears exactly 3 times in local_backup_file_path.
-    ASSERT(3 == count_substring(magic_string, local_backup_file_path));
-
-    // Run backup script
-    if (!env.run_remote_template_command(service_name, command, {remote_backup_file_path}, silent)) {
-        std::cerr << "Backup script failed on remote server: " << remote_backup_file_path << std::endl;
-        return false;
-    }
-
-    // Copy backup file from server to local
-    std::string scp_cmd = "scp -P " + env.get_SSH_PORT() + " " + 
-                         env.get_SSH_USER() + "@" + env.get_SSH_HOST() + ":" + 
-                         quote(remote_backup_file_path) + " " + quote(local_backup_file_path) + (silent ? " > /dev/null 2>&1" : "");
-    if (!env.execute_local_command(scp_cmd)) {
-        std::cerr << "Failed to copy backup file from server" << std::endl;
-        return false;
-    }
-
-    if (!silent) {
-        std::cout << "Backup created successfully. Restore with:"<<std::endl;
-        std::cout << "   dropshell restore " << server_name << " " << service_name << " " << backup_filename << std::endl;
-    }
-    return true;
-}
-
-
-} // namespace main_commands
-
-} // namespace dropshell
diff --git a/src/main_commands.hpp b/src/main_commands.hpp
deleted file mode 100644
index ddf10df..0000000
--- a/src/main_commands.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef MAIN_COMMANDS_HPP
-#define MAIN_COMMANDS_HPP
-
-#include <string>
-#include <vector>
-
-namespace dropshell {
-
-    namespace main_commands {
-
-        int init(const std::vector<std::string> &args);
-        int restore(const std::vector<std::string> &args, bool silent=false);
-        int backup(const std::vector<std::string> &args, bool silent=false);
-        } // namespace main_commands
-
-} // namespace dropshell
-
-#endif
\ No newline at end of file
diff --git a/src/service_runner.cpp b/src/service_runner.cpp
index e9af396..93f6a54 100644
--- a/src/service_runner.cpp
+++ b/src/service_runner.cpp
@@ -18,6 +18,8 @@ namespace fs = std::filesystem;
 
 namespace dropshell {
 
+static const std::string magic_string = "-_-";
+
 service_runner::service_runner(const std::string& server_name, const std::string& service_name) : 
     mServerEnv(server_name), mServer(server_name), mService(service_name), mValid(false)
 {
@@ -146,7 +148,7 @@ bool service_runner::uninstall() {
 // ------------------------------------------------------------------------------------------------
 // Run a command on the service.
 // ------------------------------------------------------------------------------------------------
-bool service_runner::run_command(const std::string& command) {
+bool service_runner::run_command(const std::string& command, std::vector<std::string> additional_args) {
     if (!mServerEnv.is_valid()) {
         std::cerr << "Error: Server service not initialized" << std::endl;
         return false;
@@ -195,6 +197,17 @@ bool service_runner::run_command(const std::string& command) {
         interactive_ssh_service();
         return true;
     }
+    if (command == "restore") {
+        if (additional_args.size() < 1) {
+            std::cerr << "Error: restore requires a backup file:" << std::endl;
+            std::cerr << "dropshell restore <server> <service> <backup-file>" << std::endl;
+            return false;
+        }
+        return restore(additional_args[0], false);
+    }
+    if (command == "backup") {
+        return backup(false);
+    }
 
     // Run the generic command
     std::vector<std::string> args; // not passed through yet.
@@ -404,23 +417,6 @@ void edit_file(const std::string &file_path, const std::string & aftertext)
     exit(EXIT_FAILURE);
 }
 
-bool service_runner::restore(std::string backup_file)
-{
-    std::string command = "restore";
-    std::string script_path = remotepath::service_template(mServer, mService) + "/" + command + ".sh";
-    if (!template_command_exists(mServiceInfo.template_name, command)) {
-        std::cout << "No restore script for " << mServiceInfo.template_name << std::endl;
-        return true; // nothing to restore.
-    }
-
-    /// TOODOOOOOO!!!!!!
-    std::cout << "Restore not implemented yet" << std::endl;
-    return true;
-
-    //    std::string run_cmd = construct_standard_command_run_cmd("restore");
-    //    return execute_ssh_command(run_cmd, "Restore script failed");
-}
-
 void service_runner::interactive_ssh_service()
 {
     std::set<std::string> used_commands = get_used_commands(mServer, mService);
@@ -446,4 +442,197 @@ void service_runner::edit_service_config()
     edit_file(config_file, aftertext);
 }
 
+
+
+bool service_runner::restore(std::string backup_file, bool silent)
+{
+    if (backup_file.empty()) {
+        std::cerr << "Error: not enough arguments.  dropshell restore <server> <service> <backup-file>" << std::endl;
+        return false;
+    }
+
+    std::string local_backups_dir = localpath::backups_path();
+    std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string();
+
+    if (! std::filesystem::exists(local_backup_file_path)) {
+        std::cerr << "Error: Backup file not found at " << local_backup_file_path << std::endl;
+        return false;
+    }
+
+    // split the backup filename into parts based on the magic string
+    std::vector<std::string> parts = dropshell::split(backup_file, magic_string);
+    if (parts.size() != 4) {
+        std::cerr << "Error: Backup file format is incompatible, - in one of the names?" << std::endl;
+        return false;
+    }
+
+    std::string backup_server_name = parts[0];
+    std::string backup_template_name = parts[1];
+    std::string backup_service_name = parts[2];
+    std::string backup_datetime = parts[3];
+
+    if (backup_template_name != mServiceInfo.template_name) {
+        std::cerr << "Error: Backup template does not match service template. Can't restore." << std::endl;
+        return false;
+    }
+
+    std::string nicedate = std::string(backup_datetime).substr(0, 10);
+
+    std::cout << "Restoring " << nicedate << " backup of " << backup_template_name << " taken from "<<backup_server_name<<", onto "<<mServer<<"/"<<mService<<std::endl;
+    std::cout << std::endl;
+    std::cout << "*** ALL DATA FOR "<<mServer<<"/"<<mService<<" WILL BE OVERWRITTEN! ***"<<std::endl;
+    std::cout << std::endl;
+    std::cout << "Are you sure you want to continue? (y/n)" << std::endl;
+    char confirm;
+    std::cin >> confirm;
+    if (confirm != 'y') {
+        std::cout << "Restore cancelled." << std::endl;
+        return false;
+    }
+
+    // run the restore script
+    std::cout << "OK, here goes..." << std::endl;
+
+    { // backup existing service
+        std::cout << "1) Backing up existing service... " << std::flush;
+        if (!backup(true)) // silent=true
+        {
+            std::cerr << std::endl;
+            std::cerr << "Error: Backup failed, restore aborted." << std::endl;
+            std::cerr << "You can try using   dropshell install "<<mServer<<" "<<mService<<"   to install the service afresh." << std::endl;
+            std::cerr << "Otherwise, stop the service, create and initialise a new one, then restore to that." << std::endl;
+            return false;
+        }
+        std::cout << "Backup complete." << std::endl;
+    }
+
+    { // restore service from backup
+        std::cout << "2) Restoring service from backup..." << std::endl;
+        std::string remote_backups_dir = remotepath::backups(mServer);
+        std::string remote_backup_file_path = remote_backups_dir + "/" + backup_file;
+
+        // Copy backup file from local to server
+        std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + quote(local_backup_file_path) + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_backup_file_path) + (silent ? " > /dev/null 2>&1" : "");
+        if (!mServerEnv.execute_local_command(scp_cmd)) {
+            std::cerr << "Failed to copy backup file from server" << std::endl;
+            return false;
+        }
+        mServerEnv.run_remote_template_command(mService, "restore", {remote_backup_file_path}, silent);
+    }
+
+    // healthcheck the service
+    std::cout << "3) Healthchecking service..." << std::endl;
+    std::string green_tick = "\033[32m✓\033[0m";
+    std::string red_cross = "\033[31m✗\033[0m";    
+    bool healthy= (mServerEnv.run_remote_template_command(mService, "status", {}, silent));
+    if (!silent)
+        std::cout << (healthy ? green_tick : red_cross) << " Service is " << (healthy ? "healthy" : "NOT healthy") << std::endl;
+
+    return true;
+}
+
+bool name_breaks_backups(std::string name)
+{
+    // if name contains -_-, return true
+    return name.find("-_-") != std::string::npos;
+}
+
+// backup the service over ssh, using the credentials from server.env (via server_env.hpp)
+// 1. run backup.sh on the server
+// 2. create a backup file with format server-service-datetime.tgz
+// 3. store it in the server's DROPSHELL_DIR/backups folder
+// 4. copy it to the local user_dir/backups folder
+
+// ------------------------------------------------------------------------------------------------
+// Backup the service.
+// ------------------------------------------------------------------------------------------------
+bool service_runner::backup(bool silent) {
+    auto service_info = get_service_info(mServer, mService);
+    if (service_info.local_service_path.empty()) {
+        std::cerr << "Error: Service not found" << std::endl;
+        return 1;
+    }
+
+    const std::string command = "backup";
+
+    if (!template_command_exists(service_info.template_name, command)) {
+        std::cout << "No backup script for " << service_info.template_name << std::endl;
+        return true; // nothing to back up.
+    }
+    
+    // Check if basic installed stuff is in place.
+    std::string remote_service_template_path = remotepath::service_template(mServer, mService);
+    std::string remote_command_script_file = remote_service_template_path + "/" + command + ".sh";
+    std::string remote_service_config_path = remotepath::service_config(mServer, mService);
+    if (!mServerEnv.check_remote_items_exist({
+        remotepath::service(mServer, mService),
+        remote_command_script_file,
+        remotefile::service_env(mServer, mService)})
+    )
+    {
+        std::cerr << "Error: Required service directories not found on remote server" << std::endl;
+        std::cerr << "Is the service installed?" << std::endl;
+        return false;
+    }
+
+    // Create backups directory on server if it doesn't exist
+    std::string remote_backups_dir = remotepath::backups(mServer);
+    if (!silent) std::cout << "Remote backups directory on "<< mServer <<": " << remote_backups_dir << std::endl;
+    std::string mkdir_cmd = "mkdir -p " + quote(remote_backups_dir);
+    if (!mServerEnv.execute_ssh_command(mkdir_cmd)) {
+        std::cerr << "Failed to create backups directory on server" << std::endl;
+        return false;
+    }
+
+    // Create backups directory locally if it doesn't exist
+    std::string local_backups_dir = localpath::backups_path();
+    if (local_backups_dir.empty()) {
+        std::cerr << "Error: Local backups directory not found - is DropShell initialised?" << std::endl;
+        return false;
+    }
+    if (!std::filesystem::exists(local_backups_dir)) 
+        std::filesystem::create_directories(local_backups_dir);
+
+    // Get current datetime for backup filename
+    auto now = std::chrono::system_clock::now();
+    auto time = std::chrono::system_clock::to_time_t(now);
+    std::stringstream datetime;
+    datetime << std::put_time(std::localtime(&time), "%Y-%m-%d_%H-%M-%S");
+    
+    if (name_breaks_backups(mServer)) {std::cerr << "Error: Server name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
+    if (name_breaks_backups(mService)) {std::cerr << "Error: Service name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
+    if (name_breaks_backups(service_info.template_name)) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
+
+    // Construct backup filename
+    std::string backup_filename = mServer + magic_string + service_info.template_name + magic_string + mService + magic_string + datetime.str() + ".tgz";
+    std::string remote_backup_file_path = remote_backups_dir + "/" + backup_filename;
+    std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_filename).string();
+
+    // assert that the backup filename is valid - -_- appears exactly 3 times in local_backup_file_path.
+    ASSERT(3 == count_substring(magic_string, local_backup_file_path));
+
+    // Run backup script
+    if (!mServerEnv.run_remote_template_command(mService, command, {remote_backup_file_path}, silent)) {
+        std::cerr << "Backup script failed on remote server: " << remote_backup_file_path << std::endl;
+        return false;
+    }
+
+    // Copy backup file from server to local
+    std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + 
+                         mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + 
+                         quote(remote_backup_file_path) + " " + quote(local_backup_file_path) + (silent ? " > /dev/null 2>&1" : "");
+    if (!mServerEnv.execute_local_command(scp_cmd)) {
+        std::cerr << "Failed to copy backup file from server" << std::endl;
+        return false;
+    }
+
+    if (!silent) {
+        std::cout << "Backup created successfully. Restore with:"<<std::endl;
+        std::cout << "   dropshell restore " << mServer << " " << mService << " " << backup_filename << std::endl;
+    }
+    return true;
+}
+
+
+
 } // namespace dropshell 
\ No newline at end of file
diff --git a/src/service_runner.hpp b/src/service_runner.hpp
index 87b61b7..ffeff31 100644
--- a/src/service_runner.hpp
+++ b/src/service_runner.hpp
@@ -30,6 +30,7 @@ typedef struct ServiceStatus {
     std::vector<int> ports;
 } ServiceStatus;
 
+
 class service_runner {
     public:
         service_runner(const std::string& server_name, const std::string& service_name);
@@ -44,7 +45,7 @@ class service_runner {
         // checking that the command exists in the service directory.
         // checking that the command is a valid .sh file.
         // checking that the {service_name}.env file exists in the service directory.
-        bool run_command(const std::string& command);
+        bool run_command(const std::string& command, std::vector<std::string> additional_args={});
 
         // check health of service. Silent.
         // 1. run status.sh on the server
@@ -79,10 +80,9 @@ class service_runner {
         // 4. remove the service directory from the server
         bool uninstall();
 
-        // restore the service over ssh, using the credentials from server.env (via server_env.hpp)
-        // 1. copy the backup file to the server's DROPSHELL_DIR/backups folder
-        // 2. run the restore.sh script on the server, passing the {service_name}.env file as an argument
-        bool restore(std::string backup_file);
+        // backup and restore
+        bool backup(bool silent=false);
+        bool restore(std::string backup_file, bool silent=false);
 
         // launch an interactive ssh session on a server or service
         // replaces the current dropshell process with the ssh process