diff --git a/.gitignore b/.gitignore
index 66fd13c903cac02eb9657cd53fb227823484401d..5daf1d4bf8d01033ec6e3a45b09282a8b9d9bb63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,8 @@
 
 # Dependency directories (remove the comment below to include it)
 # vendor/
+
+# Apps & Certs
+*.ipa
+*.apk
+*.pem
diff --git a/README.md b/README.md
index fe92e0209bf9e49b36de138228210963138fe934..7903ceca5d3436fc0d93f0e49a469dffb0c3b871 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
 # go-ipa
 Simple tool to enable OTA distribution of IPA/APK to mobile devices
+
+
+mention mkcert
diff --git a/cmd/root.go b/cmd/root.go
new file mode 100644
index 0000000000000000000000000000000000000000..3a75a71c318a48f34c8a143fd86c6ddb92e51af1
--- /dev/null
+++ b/cmd/root.go
@@ -0,0 +1,101 @@
+package cmd
+
+import (
+	"fmt"
+	"log"
+	"net/http"
+	"os"
+	"path"
+	"text/template"
+
+	"github.com/ehedenst/go-ipa/constant"
+	"github.com/joho/godotenv"
+	"github.com/phinexdaz/ipapk"
+	"github.com/skip2/go-qrcode"
+	"github.com/spf13/cobra"
+	"github.com/spf13/viper"
+)
+
+type AppInfoWithURL struct {
+	*ipapk.AppInfo
+	URL string
+}
+
+var scheme string
+var file string
+var filePath string
+var appInfo *ipapk.AppInfo
+var manifestTemplate *template.Template
+
+func qrcodeHandler(w http.ResponseWriter, req *http.Request) {
+	w.Header().Set("Content-Type", "image/png")
+	url := fmt.Sprintf("itms-services://?action=download-manifest&url=%s://%s/manifest.plist", scheme, req.Host)
+	image, _ := qrcode.Encode(url, qrcode.Medium, 256)
+	w.Write(image)
+}
+
+func manifestHandler(w http.ResponseWriter, req *http.Request) {
+	w.Header().Set("Content-Type", "text/xml")
+	appInfoWithURL := AppInfoWithURL{
+		AppInfo: appInfo,
+		URL:     fmt.Sprintf("%s://%s%s", scheme, req.Host, filePath),
+	}
+	manifestTemplate.Execute(w, appInfoWithURL)
+}
+
+func fileDownloadHandler(w http.ResponseWriter, req *http.Request) {
+	http.ServeFile(w, req, file)
+}
+
+var rootCmd = &cobra.Command{
+	Use:   "go-ipa",
+	Short: "Root Short",
+	Long:  `Root Long`,
+	Run: func(cmd *cobra.Command, args []string) {
+		var err error
+		appInfo, err = ipapk.NewAppParser(file)
+		filePath = fmt.Sprintf("/%s", path.Base(file))
+		http.HandleFunc("/qrcode.png", qrcodeHandler)
+		http.HandleFunc("/manifest.plist", manifestHandler)
+		http.HandleFunc(filePath, fileDownloadHandler)
+		addr := viper.GetString("ADDR")
+		certFile := viper.GetString("CERT")
+		if certFile != "" {
+			scheme = "https"
+			keyFile := viper.GetString("KEY")
+			err = http.ListenAndServeTLS(addr, certFile, keyFile, nil)
+		} else {
+			scheme = "http"
+			err = http.ListenAndServe(addr, nil)
+		}
+		if err != nil {
+			log.Fatal("ListenAndServe: ", err)
+		}
+	},
+}
+
+func Execute() {
+	if err := rootCmd.Execute(); err != nil {
+		fmt.Println(err)
+		os.Exit(-1)
+	}
+}
+
+func init() {
+	cobra.OnInitialize(initEnv)
+	rootCmd.PersistentFlags().StringP("addr", "a", ":9313", "addr")
+	rootCmd.PersistentFlags().StringP("cert", "c", "", "cert")
+	rootCmd.PersistentFlags().StringP("key", "k", "", "key")
+	rootCmd.Flags().StringVarP(&file, "file", "f", "", "file (required)")
+	rootCmd.MarkFlagRequired("file")
+	viper.SetEnvPrefix("IPA")
+	viper.BindPFlag("ADDR", rootCmd.PersistentFlags().Lookup("addr"))
+	viper.BindPFlag("CERT", rootCmd.PersistentFlags().Lookup("cert"))
+	viper.BindPFlag("KEY", rootCmd.PersistentFlags().Lookup("key"))
+	manifestTemplate, _ = template.New("manifest").Parse(constant.ManifestTemplate)
+}
+
+func initEnv() {
+	_ = godotenv.Load(".env")
+	viper.AutomaticEnv()
+}
diff --git a/cmd/version.go b/cmd/version.go
new file mode 100644
index 0000000000000000000000000000000000000000..0e2ccae366faa6e595e0275917bcb8c2f1c49b34
--- /dev/null
+++ b/cmd/version.go
@@ -0,0 +1,21 @@
+package cmd
+
+import (
+	"fmt"
+
+	"github.com/ehedenst/go-ipa/constant"
+	"github.com/spf13/cobra"
+)
+
+var versionCmd = &cobra.Command{
+	Use:   "version",
+	Short: "version Short",
+	Long:  `version Long`,
+	Run: func(cmd *cobra.Command, args []string) {
+		fmt.Printf("Version: %s\n", constant.Version)
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(versionCmd)
+}
diff --git a/constant/templates.go b/constant/templates.go
new file mode 100644
index 0000000000000000000000000000000000000000..ea51f0f84ea8b382d24e4788c45f8cbd8cc784c7
--- /dev/null
+++ b/constant/templates.go
@@ -0,0 +1,33 @@
+package constant
+
+var ManifestTemplate = `<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+   <key>items</key>
+   <array>
+    <dict>
+      <key>assets</key>
+      <array>
+        <dict>
+          <key>kind</key>
+          <string>software-package</string>
+          <key>url</key>
+          <string>{{.URL}}</string>
+        </dict>
+      </array>
+      <key>metadata</key>
+      <dict>
+        <key>bundle-identifier</key>
+        <string>{{.BundleId}}</string>
+        <key>bundle-version</key>
+        <string>{{.Version}}</string>
+        <key>kind</key>
+        <string>software</string>
+        <key>title</key>
+        <string>{{.Name}}</string>
+      </dict>
+    </dict>
+   </array>
+ </dict>
+</plist>`
diff --git a/constant/version.go b/constant/version.go
new file mode 100644
index 0000000000000000000000000000000000000000..958cb7b7222dd9803006dec3344f7ef7ec301671
--- /dev/null
+++ b/constant/version.go
@@ -0,0 +1,6 @@
+//go:generate sh -c "sed -i \"s/const Version = \\\".*\\\"/const Version = \\\"`git describe --tags --long`\\\"/\" version.go"
+
+package constant
+
+// Version git version number
+const Version = "0.0.0"
diff --git a/main.go b/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..0320a9c97f37e17e2beb6dbcd4d38a14a4217959
--- /dev/null
+++ b/main.go
@@ -0,0 +1,27 @@
+// Copyright © 2016 Erik Hedenström <erik@hedenstroem.com>
+//
+// 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.
+
+package main
+
+import "github.com/ehedenst/go-ipa/cmd"
+
+func main() {
+	cmd.Execute()
+}