diff --git a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt
index a0019fd56c18bc0ed2a53b4c3920e8356f5d08c5..44cf1c5ed05f073620b16a7a257481b6c2820198 100644
--- a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt
+++ b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt
@@ -31,12 +31,14 @@ import org.briarproject.mailbox.core.db.TransactionManager
 import org.briarproject.mailbox.core.lifecycle.LifecycleManager
 import org.briarproject.mailbox.core.setup.QrCodeEncoder
 import org.briarproject.mailbox.core.setup.SetupManager
+import org.briarproject.mailbox.core.system.InvalidIdException
 import org.slf4j.LoggerFactory.getLogger
 import java.util.logging.Level.ALL
 import java.util.logging.Level.INFO
 import java.util.logging.Level.WARNING
 import java.util.logging.LogManager
 import javax.inject.Inject
+import kotlin.system.exitProcess
 
 class Main : CliktCommand(
     name = "briar-mailbox",
@@ -50,6 +52,7 @@ class Main : CliktCommand(
         "-v",
         help = "Print verbose log messages"
     ).counted()
+    private val setupToken: String? by option("--setup-token", hidden = true)
 
     @Inject
     internal lateinit var coreEagerSingletons: CoreEagerSingletons
@@ -100,6 +103,13 @@ class Main : CliktCommand(
         lifecycleManager.startServices()
         lifecycleManager.waitForStartup()
 
+        if (setupToken != null) try {
+            setupManager.setToken(setupToken, null)
+        } catch (e: InvalidIdException) {
+            System.err.println("Invalid setup token")
+            exitProcess(1)
+        }
+
         // TODO this is obviously not the final code, just a stub to get us started
         val setupTokenExists = db.read { txn ->
             setupManager.getSetupToken(txn) != null
diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
index 72ed35abed28f93629bf02e6cbbb17445162cffa..c74d1fac3fba7e77b253d48935d122a1a58b4216 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt
@@ -51,11 +51,8 @@ class SetupManager @Inject constructor(
         settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER)
     }
 
-    /**
-     * Visible for testing, consider private.
-     */
     @Throws(DbException::class)
-    internal fun setToken(setupToken: String?, ownerToken: String?) {
+    fun setToken(setupToken: String?, ownerToken: String?) {
         val settings = Settings()
         if (setupToken != null) randomIdManager.assertIsRandomId(setupToken)
         settings[SETTINGS_SETUP_TOKEN] = setupToken