diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -70,7 +70,7 @@
 
 deploy:
   api_key:
-    secure: "bdJVbM9pdNqkeQb9O4mUocyA+zLAHupCLUYMPyi5jZVXF5hDPQeB93C7bMb+G4DzfYdDhDvy/VACYSGWnV2JwbSDObtAi8//wiN4Ir/AjK6aELEF8oVuoPOr4geIOMpjcUbT5JZhqqTF4Ogtd0jW97eg6LnkOZj/Nmirk7NL9FV85r3iw1MEIWBsLdHbpHKgyItOo2YKh0dM3QTZ3tjaeEhEVgd4VQQlEB2SAtueOu/lJhbjT6Y7ztGLW+UXE6ITXuG623ewA8tXt8oyeDx0HES04RVnfkDN7QIDC7Crcx7Q7Kb+yCc1cRe9QQ/9/kaeloCYd0XAKf+Bd1kyH2MIm+/Pnriz5pkM+2z1xEUhTXqXM6Wm1cXHVXRUHJQWayii1TSDp8DhVVoz8N0L3GMEIIJi1rdkO4qA84JcZkQFnH4NhvVK9Bkd/a++h6vh2WOg/nvwnOUBooNLkKik78PrIgpgTapW8yFyXrOlVqtQ9sdCmhrpQGn7Ja1P2z3tNmZgSvIcyhx/SLgHegPae5EJ9roFWRNJ9A/tlgyqNbxBdr5hLWSo3zqyJXj51cqd68tp09lloXLlC9Q2HlAejenfWYQ4KEwT1A8u+cK9lJ7pN+hgmlbQFCz9aYzokD6CCzsdJo01yQMCW2LtlKEeWiUVuA3MrWZ3l+oFQ6/npGQoOQY="
+    secure: "IZLQxO3HtTM2nqowxVOY3MhRhGZTElXUn0jpyPBkbrxLzk8Ykac15lSAGOs4MYo/GdKof8YYr2fHGChv7/PkF/HYSLFcDrY0UzpCP8QqANWjKbakQmVqU+YTtas3cq/Gk1l2tY9MGDNfMB7jk92Nh6BsA1TxReyziVPCDJv+z4UYZqQGhBxYQlVqHlcxYpS0p5gmXTFC8+io/ArGzC4jHqaZ+LmrzVMiXdDeQnVIOtQHbwWLwPb6mXBA8W5qC/IAgivb+w9aH86GUgML2t16b2/pCHQANigaeDTAseaU2PUv2fJTqexBfrAH34FJ+TQxROi8JpXu2/SVDuironTOPhUSnVd3aYNd64lOB80UmCxIWxYcYVA7olr6Qth1ZfKI0ks64sXJ7XlLDykCPqSTdnuiCEsqlHll+2ZA2uEHKuwRxMht/ZxKnW6a6GidaRp2cImBe7sMBQyiLYzf6+ZJQyy7H5beV9FsiTAyA4oxEGtl+220i0kwz6CV4+WXeoO7yv4TAKVfIEMjvHANV/kWEztuwcs3kIJzXJd1J/TdAneOHOCKGbnqDSDNeY48upwaPCQOnNA+RK4PYiA0YJ5zoq8hamtaMVzciGWMX3rFux9qC4wjgcTafFwyF3MSuF/TitAZI/xAtCOnCsZspuaBXI1nuoLoF61oixvD9xMeyNo="
   file: ats-pkg-$TARGET
   on:
     tags: true
diff --git a/ats-pkg.cabal b/ats-pkg.cabal
--- a/ats-pkg.cabal
+++ b/ats-pkg.cabal
@@ -1,5 +1,5 @@
 name:                ats-pkg
-version:             1.1.0.2
+version:             1.1.0.3
 synopsis:            Package manager for ATS
 description:         A collection of scripts to make building ATS projects easy.
 homepage:            https://github.com/vmchale/ats-pkg#readme
@@ -28,6 +28,7 @@
                      , Language.ATS.Package.Exec
                      , Language.ATS.Package.Type
                      , Language.ATS.Package.Dependency
+  other-modules:       Paths_ats_pkg
   build-depends:       base >= 4.7 && < 5
                      , http-client
                      , filemanip
@@ -45,6 +46,8 @@
                      , dhall
                      , shake-ext >= 1.2.0.0
                      , composition-prelude >= 1.1.0.1
+                     , optparse-applicative
+                     , temporary
   default-language:    Haskell2010
   if flag(development)
     ghc-options: -Werror
diff --git a/src/Language/ATS/Package/Dependency.hs b/src/Language/ATS/Package/Dependency.hs
--- a/src/Language/ATS/Package/Dependency.hs
+++ b/src/Language/ATS/Package/Dependency.hs
@@ -38,7 +38,7 @@
 
     let (lib, dirName, url') = (lib', dirName', url'') & each %~ TL.unpack
 
-    needsSetup <- not <$> doesDirectoryExist dirName
+    needsSetup <- not <$> doesDirectoryExist (dirName ++ "/atspkg.dhall")
 
     when needsSetup $ do
 
diff --git a/src/Language/ATS/Package/Exec.hs b/src/Language/ATS/Package/Exec.hs
--- a/src/Language/ATS/Package/Exec.hs
+++ b/src/Language/ATS/Package/Exec.hs
@@ -5,21 +5,83 @@
                                  ) where
 
 import           Control.Composition
-import           Data.Bool                 (bool)
-import           Dhall                     hiding (bool)
+import           Control.Lens                    hiding (argument)
+import           Data.Bool                       (bool)
+import           Data.Semigroup                  (Semigroup (..))
+import qualified Data.Text.Lazy                  as TL
+import           Data.Version                    hiding (Version (..))
+import           Dhall                           hiding (bool)
 import           Language.ATS.Package
-import           Language.ATS.Package.Type
-import           System.Directory          (doesFileExist)
-import           System.Environment        (getEnv)
+import           Language.ATS.Package.Dependency
+import           Language.ATS.Package.Type       hiding (test, version)
+import           Options.Applicative             hiding (auto)
+import           Paths_ats_pkg
+import           System.Directory                (doesFileExist,
+                                                  withCurrentDirectory)
+import           System.Environment              (getEnv)
+import           System.IO.Temp                  (withSystemTempDirectory)
 
+wrapper :: ParserInfo Command
+wrapper = info (helper <*> versionInfo <*> command')
+    (fullDesc
+    <> progDesc "The atspkg build tool for ATS-Postiats."
+    <> header "atspkg - a build tool for ATS")
+
+versionInfo :: Parser (a -> a)
+versionInfo = infoOption ("atspkg version: " ++ showVersion version) (short 'v' <> long "version" <> help "Show version")
+
+data Command = Install
+             | Build { _targets :: [String] }
+             | Clean
+             | Test
+             | Fetch { _url :: String }
+
+command' :: Parser Command
+command' = hsubparser
+    (command "install" (info (pure Install) (progDesc "Install all binaries to $HOME/.local/bin"))
+    <> command "clean" (info (pure Clean) (progDesc "Clean current project directory"))
+    <> command "fetch" (info fetch (progDesc "Fetch and install a binary package"))
+    <> command "build" (info build (progDesc "Build current package targets"))
+    <> command "test" (info (pure Test) (progDesc "Test current package"))
+    )
+
+build :: Parser Command
+build = Build <$> many
+    (argument str
+    (metavar "TARGET"
+    <> help "Targets to build"))
+
+fetch :: Parser Command
+fetch = Fetch <$>
+    argument str
+    (metavar "URL"
+    <> help "URL pointing to a tarball containing the package to be installed.")
+
 check :: IO Bool
 check = do
     home <- getEnv "HOME"
     v <- want
     doesFileExist (home ++ "/.atspkg/" ++ show v ++ "/bin/patscc")
 
+fetchPkg :: String -> IO ()
+fetchPkg pkg = withSystemTempDirectory "atspkg" $ \p -> do
+    let (lib, dirName, url') = ("atspkg", p, pkg) & each %~ TL.pack
+    fetchDeps [Dependency lib dirName url']
+    withCurrentDirectory (p ++ "/polyglot-0.3.27") (mkPkg ["install"])
+
 exec :: IO ()
-exec = bool (buildAll >> mkPkg) mkPkg =<< check
+exec = execParser wrapper >>= run
+
+-- https://github.com/vmchale/polyglot/archive/0.3.27.tar.gz
+run :: Command -> IO ()
+run (Fetch u) = fetchPkg u
+run c = bool (buildAll >> mkPkg rs) (mkPkg rs) =<< check
+    where rs = g c
+          g Install    = ["install"]
+          g Clean      = ["clean"]
+          g (Build ts) = ts
+          g Test       = ["test"]
+          g _          = undefined
 
 want :: IO Version
 want = Version . compiler <$> input auto "./atspkg.dhall"
diff --git a/src/Language/ATS/Package/Type.hs b/src/Language/ATS/Package/Type.hs
--- a/src/Language/ATS/Package/Type.hs
+++ b/src/Language/ATS/Package/Type.hs
@@ -20,6 +20,8 @@
 import           Development.Shake.Man
 import           Dhall
 import           Language.ATS.Package.Dependency
+import           System.Directory                (getCurrentDirectory,
+                                                  listDirectory)
 
 options :: ShakeOptions
 options = shakeOptions { shakeFiles = ".atspkg"
@@ -27,13 +29,15 @@
                        , shakeProgress = progressSimple
                        }
 
-mkPkg :: IO ()
-mkPkg = shakeArgs options $
+-- TODO verbosity & coloring?
+mkPkg :: [String] -> IO ()
+mkPkg rs = shake options $
+    want rs >>
     mkTest >>
     mkClean >>
     mkManpage >>
     mkInstall >>
-    (pkgToAction =<< getConfig)
+    (pkgToAction rs =<< getConfig)
 
 mkManpage :: Rules ()
 mkManpage = do
@@ -43,7 +47,10 @@
         _      -> pure ()
 
 getConfig :: MonadIO m => m Pkg
-getConfig = liftIO (input auto "./atspkg.dhall")
+getConfig = liftIO $ do
+    d <- getCurrentDirectory
+    print =<< listDirectory d
+    input auto (TL.pack d <> "/atspkg.dhall")
 
 manTarget :: Text -> FilePath
 manTarget m = TL.unpack m -<.> "1"
@@ -80,15 +87,16 @@
         need tests
         mapM_ cmd_ tests
 
-pkgToAction :: Pkg -> Rules ()
-pkgToAction (Pkg bs ts mt v v' ds) = do
+pkgToAction :: [String] -> Pkg -> Rules ()
+pkgToAction rs (Pkg bs ts mt v v' ds) = do
     liftIO $ fetchDeps ds
     action (need ["atspkg.dhall"])
     mapM_ g (bs ++ ts)
     let bins = TL.unpack . target <$> bs
-    case mt of
-        (Just m) -> want (manTarget m : bins)
-        Nothing  -> want bins
+    when (null rs) $
+        case mt of
+            (Just m) -> want (manTarget m : bins)
+            Nothing  -> want bins
 
     where g (Bin s t ls gc') = atsBin (Version v) (Version v') gc' (TL.unpack <$> ls) (TL.unpack s) (TL.unpack t)
 
@@ -97,6 +105,8 @@
                , libs   :: [Text] -- ^ Libraries to link against (e.g. @[ "pthread" ]@)
                , gc     :: Bool } -- ^ Whether to use the garbage collector
          deriving (Show, Eq, Generic, Interpret)
+
+-- data RemotePkg = RemotePkg Pkg Text
 
 data Pkg = Pkg { bin          :: [Bin] -- ^ List of binaries to be built
                , test         :: [Bin] -- ^ List of test suites
