diff --git a/miniapp/io.cpp b/miniapp/io.cpp
index 3dd5e96dfc3432581fc26103275644a6ca1fb86e..330f1a20b231ff22f1c2a07b8d6828184aeef41c 100644
--- a/miniapp/io.cpp
+++ b/miniapp/io.cpp
@@ -183,10 +183,16 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
             false, defopts.dry_run_ranks, "positive integer", cmd);
         TCLAP::SwitchArg profile_only_zero_arg(
              "z", "profile-only-zero", "Only output profile information for rank 0", cmd, false);
+        TCLAP::SwitchArg verbose_arg(
+             "v", "verbose", "Present more verbose information to stdout", cmd, false);
 
         cmd.reorder_arguments();
         cmd.parse(argc, argv);
 
+        // Handle verbosity separately from other options: it is not considered part
+        // of the saved option state.
+        options.verbose = verbose_arg.getValue();
+
         std::string ifile_name = ifile_arg.getValue();
         if (ifile_name != "") {
             // Read parameters from specified JSON file first, to allow
@@ -324,6 +330,12 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
             throw usage_error("unable to write to model parameter file "+save_file);
         }
     }
+
+    // If verbose output requested, emit option summary.
+    if (options.verbose) {
+        std::cout << options << "\n";
+    }
+
     return options;
 }
 
diff --git a/miniapp/io.hpp b/miniapp/io.hpp
index a005cd290daf065fd4fc52121a04b08699c3e3e4..8e6b7b1f54715d78536820ec70f569614481c4c7 100644
--- a/miniapp/io.hpp
+++ b/miniapp/io.hpp
@@ -57,6 +57,9 @@ struct cl_options {
 
     // Report (inefficiently) on number of cell compartments in sim.
     bool report_compartments = false;
+
+    // Be more verbose with informational messages.
+    bool verbose = false;
 };
 
 class usage_error: public std::runtime_error {