diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2007 Sebastian Philipp
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/hunt-server-cli.cabal b/hunt-server-cli.cabal
new file mode 100644
--- /dev/null
+++ b/hunt-server-cli.cabal
@@ -0,0 +1,59 @@
+name:          hunt-server-cli
+version:       0.2.0.0
+license:       MIT
+license-file:  LICENSE
+author:        Chris Reumann, Ulf Sauer, Sebastian Philipp
+copyright:     Chris Reumann, Ulf Sauer, Sebastian Philipp
+maintainer:    Chris Reumann, Ulf Sauer, Sebastian Philipp
+stability:     experimental
+category:      Console
+synopsis:      A Command line Interface for the Hunt server.
+homepage:      http://github.com/hunt-framework
+description:   A Command line Interface for the Hunt server.
+cabal-version: >=1.6
+build-type:    Simple
+
+-- extra-source-files:
+--     README
+
+source-repository head
+  type:        git
+  location:    https://github.com/hunt-framework/hunt.git
+
+executable hunt-server-cli
+  main-is:      Main.hs
+
+  other-modules: Hunt.Converter.CSV
+
+  build-depends:   base                   >= 4 && < 5
+                 , binary
+                 , bytestring             >= 0.9.1     && < 1
+                 , data-default
+                 , aeson
+                 , aeson-pretty
+                 , containers             >= 0.5
+                 , time
+                 , hunt-searchengine      >= 0.2
+                 , hunt-client
+                 , hslogger
+                 , http-types             >= 0.8.0
+                 , string-conversions
+                 , mtl                    >= 1.1       && < 3
+                 , text                   >= 1         && < 2
+                 , docopt
+                 , csv-conduit            >= 0.6
+                 , resourcet >= 0.3
+                 , conduit
+                 , conduit-extra
+                 , transformers
+                 , unordered-containers
+
+  hs-source-dirs: src
+
+  ghc-options:   -Wall
+
+  if impl( ghc >= 7 )
+    ghc-options: -rtsopts
+                 -fwarn-tabs
+
+  extensions: OverloadedStrings
diff --git a/src/Hunt/Converter/CSV.hs b/src/Hunt/Converter/CSV.hs
new file mode 100644
--- /dev/null
+++ b/src/Hunt/Converter/CSV.hs
@@ -0,0 +1,45 @@
+module Hunt.Converter.CSV where
+
+import           Prelude hiding ( mapM_, map, putStrLn)
+
+import           Control.Applicative ((<$>))
+
+import           Data.Aeson.Encode.Pretty (encodePretty)
+import           Data.Aeson (Value(..))
+
+import           Data.ByteString.Lazy.Char8  (putStrLn)
+
+import           Data.Conduit (Conduit, ($=), ($$))
+import           Data.Conduit.Binary hiding ( mapM_)
+import           Data.Conduit.List  (consume)
+
+import           Data.CSV.Conduit (defCSVSettings, intoCSV, MapRow, runResourceT)
+
+import qualified Data.Map
+
+import           Data.String.Conversions (cs)
+import           Data.Text (Text)
+
+import qualified Hunt.Common.DocDesc (DocDesc, fromList)
+import qualified Hunt.ClientInterface as H
+import qualified Hunt.Conduit as HC
+
+convertToDocument :: FilePath -> Int -> MapRow Text -> H.ApiDocument
+convertToDocument fileName i row = H.listToApiDoc uri elems elems
+    where
+    uri = (cs $ "file://" ++ fileName ++ "/" ++ (show i))
+    elems = (Data.Map.toList row)
+
+rowToApiDocument :: (Monad m) => FilePath -> Conduit (MapRow Text) m H.Command
+rowToApiDocument fileName = HC.makeInsertsWithIndex (convertToDocument fileName)
+
+
+convert :: FilePath -> IO ()
+convert fileName = do
+    list <- runResourceT $
+      sourceFile fileName $=
+      intoCSV defCSVSettings $=
+      rowToApiDocument fileName $$
+      consume
+    putStrLn $ encodePretty list
+
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,176 @@
+{-# LANGUAGE DoAndIfThenElse #-}
+-- ----------------------------------------------------------------------------
+{- |
+  Main module for the executable.
+-}
+-- ----------------------------------------------------------------------------
+
+module Main where
+
+import           Control.Applicative       ((<$>), (<|>))
+import           Control.Monad             (when)
+
+import           Data.Aeson                (decode)
+import           Data.Aeson.Encode.Pretty  (encodePretty)
+import           Data.ByteString.Lazy      (ByteString)
+-- import           Data.Char                 (toUpper)
+-- import           Data.Map                  (keys)
+import           Data.Maybe                (fromJust)
+import           Data.String.Conversions   (cs)
+import           Data.Text                 (Text)
+import           Data.Time.Clock.POSIX     (getPOSIXTime)
+
+import           System.Console.Docopt     (argument, command, getArg,
+                                            isPresent, longOption,
+                                            optionsWithUsage)
+import           System.Environment        (getArgs)
+import qualified System.IO                 as System (stderr)
+import qualified System.Log.Formatter      as Log (simpleLogFormatter)
+import qualified System.Log.Handler        as Log (setFormatter)
+import qualified System.Log.Handler.Simple as Log (streamHandler)
+import qualified System.Log.Logger         as Log
+
+import qualified Hunt.ClientInterface      as H
+import qualified Hunt.Converter.CSV        as CSV (convert)
+import qualified Hunt.Server.Client        as HC
+
+usage :: String
+usage = unlines [
+    "hunt-server-cli"
+    , ""
+    , "Usage:"
+    , "  hunt-server-cli eval [--server SERVER] <file>"
+    , "  hunt-server-cli load [--server SERVER] <file>"
+    , "  hunt-server-cli store [--server SERVER] <file>"
+    , "  hunt-server-cli search [--server SERVER] [--max MAX] [--offset OFFSET] <query>"
+    , "  hunt-server-cli completion [--server SERVER] <query>"
+    , "  hunt-server-cli make-schema <file>"
+    , "  hunt-server-cli make-insert <file>"
+    , "  hunt-server-cli from-csv <file>"
+    , ""
+    , ""
+    , "Options:"
+    , "  -h --help           Show this screen."
+    , "  --server=SERVER     Use this hunt server [default: http://localhost:3000]"
+    , "  --max=MAX           Request at most MAX results [default: 20]"
+    , "  --offset=OFFSET     Request results from offset OFFSET [default: 0]"
+    , "  make-schema <file>  prints a simple schema for this document" ]
+
+-- ------------------------------------------------------------
+
+-- | Initializes the loggers with the given priority.
+initLoggers :: Log.Priority -> IO ()
+initLoggers level = do
+    handlerBare <- Log.streamHandler System.stderr Log.DEBUG
+    let handler = Log.setFormatter handlerBare $ Log.simpleLogFormatter "[$time : $loggername : $prio] $msg"
+
+    Log.updateGlobalLogger "" (Log.setLevel level . Log.setHandlers [handler])
+    rl <- Log.getRootLogger
+    Log.saveGlobalLogger rl
+
+data Options = Options
+  { optLogLevel ::Log.Priority
+  }
+
+printTime :: IO a -> IO a
+printTime act = do
+
+  start <- getTime
+  result <- act
+  end <- getTime
+  let delta = end - start
+  Log.infoM "main" $ "took " ++ (show (delta))
+  return result
+  where
+  getTime = getPOSIXTime -- realToFrac `fmap`
+
+
+readDocuments :: ByteString -> IO [H.ApiDocument]
+readDocuments bs = maybe (do {(Log.infoM "main" $  "unable to parse ApiDocuments") ; return []}) return docs
+  where
+  docs = ((return <$> decode bs) <|> decode bs <|> (H.insertCmdsToDocuments <$> decode bs))
+
+makeSchema :: FilePath -> IO String
+makeSchema fileName = do
+  file <- cs <$> readFile fileName
+  docs <- readDocuments file
+  let cmds = H.createContextCommands docs
+  return $ cs $ encodePretty cmds
+
+makeInserts :: FilePath -> IO String
+makeInserts fileName = do
+  file <- cs <$> readFile fileName
+  docs <- readDocuments file
+  return $ cs $ encodePretty $ H.cmdSequence $ H.cmdInsertDoc <$> docs
+
+evalCmd :: String -> H.Command -> IO ByteString
+evalCmd server cmd = do
+  encodePretty <$> HC.evalOnServer_ (cs server) cmd
+
+eval :: String -> FilePath -> IO ByteString
+eval server fileName = do
+  file <- readFile fileName
+  evalCmd server $ fromJust $ decode $ cs file
+
+search :: String -> String -> Int -> Int -> IO ByteString
+search server query maxResults offsetResults
+    = cs
+      <$> (encodePretty :: H.LimitedResult H.ApiDocument -> ByteString)
+      <$> HC.withHuntServer (cs server) (HC.getQuery (cs query) maxResults offsetResults )
+
+autocomplete :: String -> String -> IO String
+autocomplete server query
+    = cs
+      <$> (encodePretty :: [Text] -> ByteString)
+      <$> (HC.withHuntServer (cs server) (HC.getAutocomplete $ cs query))
+
+-- | Main function for the executable.
+main :: IO ()
+main = do
+  initLoggers Log.DEBUG
+  args <- optionsWithUsage usage =<< getArgs
+
+  let isCommand str = args `isPresent` (command str)
+      fileArgument = args `getArg` (argument "<file>")
+      queryArgument = args `getArg` (argument "<query>")
+
+  server <- do
+      if (args `isPresent` (longOption "server")) then
+          args `getArg` (longOption "server")
+      else
+          return "http://localhost:3000"
+
+  maxResults <- read <$> (args `getArg` (longOption "max"))
+  offsetResults <- read <$> (args `getArg` (longOption "offset"))
+
+  when (isCommand "eval") $ do
+    file <- fileArgument
+    putStr =<< (printTime $ cs <$> eval server file)
+
+  when (isCommand "load") $ do
+    file <- fileArgument
+    putStr =<< cs <$> (evalCmd server $ H.cmdLoadIndex file)
+
+  when (isCommand "store") $ do
+    file <- fileArgument
+    putStr =<< cs <$> (evalCmd server $ H.cmdStoreIndex file)
+
+  when (isCommand "search") $ do
+    query <- queryArgument
+    putStr =<< (printTime $ cs <$> search server query maxResults offsetResults)
+
+  when (isCommand "completion") $ do
+    query <- queryArgument
+    putStr =<< (printTime $ cs <$> autocomplete server query)
+
+  when (isCommand "from-csv") $ do
+    CSV.convert =<< fileArgument
+
+  when (isCommand "make-schema") $ do
+    file <- fileArgument
+    putStr =<< makeSchema file
+
+  when (isCommand "make-insert") $ do
+    file <- fileArgument
+    putStr =<< makeInserts file
+
