diff --git a/htest/Test/Ganeti/HTools/CLI.hs b/htest/Test/Ganeti/HTools/CLI.hs
index 5b6b369ec0aefdca1cf960a42b6a643495b6c06c..2ecff7528363690bf2ab8e223d2b93e6188dd43a 100644
--- a/htest/Test/Ganeti/HTools/CLI.hs
+++ b/htest/Test/Ganeti/HTools/CLI.hs
@@ -119,7 +119,7 @@ case_wrong_arg =
 -- | Test that all binaries support some common options.
 case_stdopts :: Assertion
 case_stdopts =
-  mapM_ (\(name, (_, o, a)) -> do
+  mapM_ (\(name, (_, o, a, _)) -> do
            o' <- o
            checkEarlyExit defaultOptions name
              (o' ++ genericOpts) a) Program.personalities
diff --git a/htools/Ganeti/Common.hs b/htools/Ganeti/Common.hs
index 6a41548974edecb4635f259722f0ad22ab45c87f..1906b7f492618e7d477d493ecc09887cc3bac196 100644
--- a/htools/Ganeti/Common.hs
+++ b/htools/Ganeti/Common.hs
@@ -96,6 +96,7 @@ data ArgCompletion = ArgCompletion OptCompletion Int (Maybe Int)
 type Personality a = ( a -> [String] -> IO () -- The main function
                      , IO [GenericOptType a]  -- The options
                      , [ArgCompletion]        -- The description of args
+                     , String                 -- Description
                      )
 
 -- | Personality lists type, common across all binaries that expose
@@ -209,8 +210,9 @@ formatCmdUsage prog personalities =
                , ""
                , "Commands:"
                ]
-      rows = map (\(cmd, _) ->
-                    printf " %-*s" mlen cmd::String) sorted
+      rows = map (\(cmd, (_, _, _, desc)) ->
+                    -- FIXME: not wrapped here
+                    printf " %-*s - %s" mlen cmd desc::String) sorted
   in unlines $ header ++ rows
 
 -- | Displays usage for a program and exits.
@@ -266,7 +268,7 @@ parseOptsCmds defaults argv progname personalities genopts = do
                        [] -> usage False
   case cmd `lookup` personalities of
     Nothing -> usage False
-    Just (mainfn, optdefs, argdefs) -> do
+    Just (mainfn, optdefs, argdefs, _) -> do
       optdefs' <- optdefs
       (opts, args) <- parseOpts defaults cmd_args progname
                       (optdefs' ++ genopts) argdefs
diff --git a/htools/Ganeti/DataCollectors/Program.hs b/htools/Ganeti/DataCollectors/Program.hs
index 3bd9b2fb9e0c0471c81fae1c4aff0052d2abd0dd..4e5ce133d9e299e0affb950edb6b750e4bf6701f 100644
--- a/htools/Ganeti/DataCollectors/Program.hs
+++ b/htools/Ganeti/DataCollectors/Program.hs
@@ -32,5 +32,7 @@ import qualified Ganeti.DataCollectors.Drbd as Drbd
 
 -- | Supported binaries.
 personalities :: PersonalityList Options
-personalities = [ ("drbd",   (Drbd.main, Drbd.options, Drbd.arguments))
+personalities = [ ("drbd",   (Drbd.main, Drbd.options, Drbd.arguments,
+                             "gathers and displays DRBD statistics in JSON\
+                             \ format"))
                 ]
diff --git a/htools/Ganeti/HTools/Program.hs b/htools/Ganeti/HTools/Program.hs
index 04ed53fb5f88efe953dafc5c529d8a8cc8991739..7e9554643715fb5f14685bd78152b02257ea32fd 100644
--- a/htools/Ganeti/HTools/Program.hs
+++ b/htools/Ganeti/HTools/Program.hs
@@ -39,10 +39,27 @@ import qualified Ganeti.HTools.Program.Hinfo as Hinfo
 
 -- | Supported binaries.
 personalities :: PersonalityList Options
-personalities = [ ("hail",   (Hail.main,   Hail.options,   Hail.arguments))
-                , ("hbal",   (Hbal.main,   Hbal.options,   Hbal.arguments))
-                , ("hcheck", (Hcheck.main, Hcheck.options, Hcheck.arguments))
-                , ("hscan",  (Hscan.main,  Hscan.options,  Hscan.arguments ))
-                , ("hspace", (Hspace.main, Hspace.options, Hspace.arguments))
-                , ("hinfo",  (Hinfo.main,  Hinfo.options,  Hinfo.arguments))
-                ]
+personalities =
+  [ ("hail",   (Hail.main,   Hail.options,   Hail.arguments,
+                "Ganeti IAllocator plugin that implements the instance\
+                \ placement and movement using the same algorithm as\
+                \ hbal(1)"))
+  , ("hbal",   (Hbal.main,   Hbal.options,   Hbal.arguments,
+                "cluster balancer that looks at the current state of\
+                \ the cluster and computes a series of steps designed\
+                \ to bring the cluster into a better state"))
+  , ("hcheck", (Hcheck.main, Hcheck.options, Hcheck.arguments,
+               "cluster checker; prints information about cluster's\
+               \ health and checks whether a rebalance done using\
+               \ hbal would help"))
+  , ("hscan",  (Hscan.main,  Hscan.options,  Hscan.arguments,
+               "tool for scanning clusters via RAPI and saving their\
+               \ data in the input format used by hbal(1) and hspace(1)"))
+  , ("hspace", (Hspace.main, Hspace.options, Hspace.arguments,
+               "computes how many additional instances can be fit on a\
+               \ cluster, while maintaining N+1 status."))
+  , ("hinfo",  (Hinfo.main,  Hinfo.options,  Hinfo.arguments,
+               "cluster information printer; it prints information\
+               \ about the current cluster state and its residing\
+               \ nodes/instances"))
+  ]
diff --git a/htools/htools.hs b/htools/htools.hs
index 1b491e2b41f22929b7c4ae4a3b7a76fe5f04b749..2dabb5b35d3f25b81ac27802deb437ff52140d33 100644
--- a/htools/htools.hs
+++ b/htools/htools.hs
@@ -54,7 +54,7 @@ main = do
       boolnames = map (\(x, y) -> (x == name, Just y)) personalities
   case select Nothing boolnames of
     Nothing -> usage name
-    Just (fn, options, arguments) -> do
+    Just (fn, options, arguments, _) -> do
          cmd_args <- getArgs
          real_options <- options
          (opts, args) <- parseOpts cmd_args name (real_options ++ genericOpts)