diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for sensu-run
 
+## 0.1.1 -- 2017-06-09
+
+* Add --version option
+
 ## 0.1.0 -- 2017-06-07
 
 * Fix a bug that ignores --handle option by accident
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,78 @@
+# sensu-run
+[![Hackage](https://img.shields.io/hackage/v/sensu-run.svg)](http://hackage.haskell.org/package/sensu-run)
+[![Hackage-Deps](https://img.shields.io/hackage-deps/v/sensu-run.svg)](http://packdeps.haskellers.com/feed?needle=sensu-run)
+[![Stackage Nightly](http://stackage.org/package/sensu-run/badge/nightly)](http://stackage.org/nightly/package/sensu-run)
+[![Build Status](https://travis-ci.org/maoe/sensu-run.svg?branch=master)](https://travis-ci.org/maoe/sensu-run)
+[![Build status](https://ci.appveyor.com/api/projects/status/k9594kkn4tncotqt/branch/master?svg=true)](https://ci.appveyor.com/project/maoe/sensu-run/branch/master)
+
+`sensu-run` runs a command and send its result to Sensu server using the [client socket input](https://sensuapp.org/docs/latest/reference/clients.html#client-socket-input) or via the Sensu API. It is useful to monitor cron jobs for example.
+
+## Installation
+
+Install [stack](https://docs.haskellstack.org/en/stable/README/).
+
+```sh
+stack install --resolver=nightly sensu-run
+```
+will install the `sensu-run` command in `~/.local/bin`.
+
+## Usage
+
+```console
+% sensu-run --help
+Usage: sensu-run ([-n|--name NAME] [--source SOURCE] [--ttl SECONDS]
+                 [--timeout SECONDS] [--handler HANDLER] ([--port PORT] |
+                 [--server URL]) [--dry|--dry-run] [-s|--shell] [COMMAND] |
+                 [-v|--version])
+
+Available options:
+  -h,--help                Show this help text
+  -n,--name NAME           The name of the check
+  --source SOURCE          The check source, used to create a JIT Sensu client
+                           for an external resource
+  --ttl SECONDS            The time to live in seconds until check results are
+                           considered stale
+  --timeout SECONDS        The check executaion duration timeout in seconds
+  --handler HANDLER        Sensu event handler(s) to use for events created by
+                           the check
+  --port PORT              Send results to the local sensu-client listening on
+                           the specified port (default: 3030)
+  --server URL             Send results to the specified Sensu server
+  -s,--shell               Execute the command using the shell
+```
+
+`--dry-run` option is useful to check the JSON output:
+
+```console
+% sensu-run --name check-home-src-size --handler foo --dry-run -- du -s $HOME/src | jq .
+{
+  "name": "check-home-src-size",
+  "command": "du -s /home/maoe/src",
+  "issued": 1496966954,
+  "executed": 1496966954,
+  "duration": 1.235584,
+  "status": 0,
+  "output": "44567740\t/home/maoe/src\n",
+  "handlers": [
+    "foo"
+  ]
+}
+```
+
+Without the `--dry-run` option, `sensu-run` sends the output to localhost:PORT, which is expected to be listened by `sensu-client`.
+
+`sensu-run` sets the status field depending on the command exit code and timeout:
+
+| command exit code | `status` field |
+|-------------------|----------------|
+| 0                 | 0 (OK)         |
+| non-zero          | 2 (CRITICAL)   |
+| command timed out | 3 (UNKNOWN)    |
+
+### Sensu API
+
+`sensu-run` supports posting check results via Sensu API as well. Use `--server` option to specify Sensu server addresses. If multiple servers are specified, `sensu-run` tries them one by one until it succeeds.
+
+```sh
+sensu-run --name check-true --handler foo --server sensu1.example.com --server sensu2.example.com --dry-run -- du -s $HOME/src
+```
diff --git a/sensu-run.cabal b/sensu-run.cabal
--- a/sensu-run.cabal
+++ b/sensu-run.cabal
@@ -1,5 +1,5 @@
 name: sensu-run
-version: 0.1.0
+version: 0.1.1
 synopsis: A tool to send command execution results to Sensu
 description:
   @sensu-run@ is a command line tool to send command execution results to Sensu
@@ -13,7 +13,9 @@
 bug-reports: https://github.com/maoe/sensu-run/issues
 category: System
 build-type: Simple
-extra-source-files: CHANGELOG.md
+extra-source-files:
+  CHANGELOG.md
+  README.md
 cabal-version: >= 1.10
 tested-with: GHC == 8.0.2
 
diff --git a/sensu-run.hs b/sensu-run.hs
--- a/sensu-run.hs
+++ b/sensu-run.hs
@@ -15,9 +15,11 @@
 import Data.Foldable
 import Data.List.NonEmpty (NonEmpty)
 import Data.Maybe
+import Data.Monoid
 import System.Exit
 import System.IO
 import qualified Data.List.NonEmpty as NE
+import qualified Data.Version as V
 import qualified System.Timeout as Timeout
 
 import Control.Lens hiding ((.=))
@@ -40,40 +42,46 @@
 import qualified Network.Wreq as W
 import qualified Options.Applicative as O
 
+import qualified Paths_sensu_run as Paths
+
 main :: IO ()
 main = do
   issued <- getCurrentTime
-  Options {..} <- O.execParser $ O.info (O.helper <*> options) O.fullDesc
-  withSystemTempFile "sensu-run.XXX" $ \path hdl -> do
-    executed <- getCurrentTime
-    rawStatus <- bracket
-      (startProcess cmdspec hdl)
-      terminateProcess
-      (withTimeout timeout . waitForProcess)
-    exited <- getCurrentTime
-    rawOutput <- BL.readFile path
-    let
-      encoded = encode CheckResult
-        { command = cmdspec
-        , output = TL.decodeUtf8With TE.lenientDecode rawOutput
-        , status = case rawStatus of
-          Nothing -> UNKNOWN
-          Just ExitSuccess -> OK
-          Just ExitFailure {} -> CRITICAL
-        , duration = diffUTCTime exited executed
-        , ..
-        }
-    if dryRun
-      then BL8.putStrLn encoded
-      else case endpoint of
-        ClientSocketInput port -> sendToClientSocketInput port encoded
-        SensuServer urls -> sendToSensuServer urls encoded
-    case rawStatus of
-      Just ExitSuccess -> exitSuccess
-      Nothing -> do
-        hPutStrLn stderr $ showCmdSpec cmdspec ++ " timed out"
-        exitFailure
-      Just ExitFailure {} -> exitFailure
+  opts <- O.execParser $ O.info (O.helper <*> options) O.fullDesc
+  case opts of
+    ShowVersion -> do
+      putStrLn $ "sensu-run " ++ V.showVersion Paths.version
+      exitSuccess
+    RunOptions {..} -> withSystemTempFile "sensu-run.XXX" $ \path hdl -> do
+      executed <- getCurrentTime
+      rawStatus <- bracket
+        (startProcess cmdspec hdl)
+        terminateProcess
+        (withTimeout timeout . waitForProcess)
+      exited <- getCurrentTime
+      rawOutput <- BL.readFile path
+      let
+        encoded = encode CheckResult
+          { command = cmdspec
+          , output = TL.decodeUtf8With TE.lenientDecode rawOutput
+          , status = case rawStatus of
+            Nothing -> UNKNOWN
+            Just ExitSuccess -> OK
+            Just ExitFailure {} -> CRITICAL
+          , duration = diffUTCTime exited executed
+          , ..
+          }
+      if dryRun
+        then BL8.putStrLn encoded
+        else case endpoint of
+          ClientSocketInput port -> sendToClientSocketInput port encoded
+          SensuServer urls -> sendToSensuServer urls encoded
+      case rawStatus of
+        Just ExitSuccess -> exitSuccess
+        Nothing -> do
+          hPutStrLn stderr $ showCmdSpec cmdspec ++ " timed out"
+          exitFailure
+        Just ExitFailure {} -> exitFailure
 
 sendToClientSocketInput
   :: PortNumber -- ^ Listening port of Sensu client socket
@@ -140,16 +148,18 @@
   Just n -> Timeout.timeout (round $ n * 10^(6 :: Int))  io
   Nothing -> Just <$> io
 
-data Options = Options
-  { name :: T.Text
-  , cmdspec :: CmdSpec
-  , source :: Maybe T.Text
-  , ttl :: Maybe NominalDiffTime
-  , timeout :: Maybe NominalDiffTime
-  , handlers :: [T.Text]
-  , endpoint :: Endpoint
-  , dryRun :: Bool
-  }
+data Options
+  = ShowVersion
+  | RunOptions
+    { name :: T.Text
+    , cmdspec :: CmdSpec
+    , source :: Maybe T.Text
+    , ttl :: Maybe NominalDiffTime
+    , timeout :: Maybe NominalDiffTime
+    , handlers :: [T.Text]
+    , endpoint :: Endpoint
+    , dryRun :: Bool
+    }
 
 data Endpoint
   = ClientSocketInput PortNumber
@@ -162,46 +172,50 @@
   -- client HTTP sockets listen on 3031.
 
 options :: O.Parser Options
-options = do
-  name <- textOption $ mconcat
-    [ O.short 'n'
-    , O.long "name"
-    , O.metavar "NAME"
-    , O.help "The name of the check"
-    ]
-  source <- O.optional $ textOption $ mconcat
-    [ O.long "source"
-    , O.metavar "SOURCE"
-    , O.help $ unlines
-      [ "The check source, used to create a JIT Sensu client for an"
-      , "external resource" ]
-    ]
-  ttl <- durationOption $ mconcat
-    [ O.long "ttl"
-    , O.metavar "SECONDS"
-    , O.help "The time to live in seconds until check results are considered stale"
-    ]
-  timeout <- durationOption $ mconcat
-    [ O.long "timeout"
-    , O.metavar "SECONDS"
-    , O.help "The check executaion duration timeout in seconds"
-    ]
-  handlers <- O.some $ textOption $ mconcat
-    [ O.long "handler"
-    , O.metavar "HANDLER"
-    , O.help "Sensu event handler(s) to use for events created by the check"
-    ]
-  endpoint <- asum
-    [ ClientSocketInput <$> portOption
-    , SensuServer . NE.fromList <$> O.some serverOption
-    ]
-  dryRun <- O.switch $ mconcat
-    [ O.long "dry-run"
-    , O.long "dry"
-    ]
-  cmdspec <- cmdSpecOption
-  return Options {..}
+options = asum
+  [ runOptions
+  , ShowVersion <$ O.switch (O.long "version" <> O.short 'v')
+  ]
   where
+    runOptions = do
+      name <- textOption $ mconcat
+        [ O.short 'n'
+        , O.long "name"
+        , O.metavar "NAME"
+        , O.help "The name of the check"
+        ]
+      source <- O.optional $ textOption $ mconcat
+        [ O.long "source"
+        , O.metavar "SOURCE"
+        , O.help $ unlines
+          [ "The check source, used to create a JIT Sensu client for an"
+          , "external resource" ]
+        ]
+      ttl <- durationOption $ mconcat
+        [ O.long "ttl"
+        , O.metavar "SECONDS"
+        , O.help "The time to live in seconds until check results are considered stale"
+        ]
+      timeout <- durationOption $ mconcat
+        [ O.long "timeout"
+        , O.metavar "SECONDS"
+        , O.help "The check executaion duration timeout in seconds"
+        ]
+      handlers <- O.some $ textOption $ mconcat
+        [ O.long "handler"
+        , O.metavar "HANDLER"
+        , O.help "Sensu event handler(s) to use for events created by the check"
+        ]
+      endpoint <- asum
+        [ ClientSocketInput <$> portOption
+        , SensuServer . NE.fromList <$> O.some serverOption
+        ]
+      dryRun <- O.switch $ mconcat
+        [ O.long "dry-run"
+        , O.long "dry"
+        ]
+      cmdspec <- cmdSpecOption
+      return RunOptions {..}
     textOption m = T.pack <$> O.strOption m
     durationOption m =
       fmap (realToFrac @Double) <$> O.optional (O.option O.auto m)
