diff --git a/.gitignore b/.gitignore
index 69ad294..5ec618d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 .python-version
 __pycache__/
+build/
+*.egg-info/
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..7fb8e6c
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,24 @@
+from setuptools import find_packages, setup
+
+setup(
+    name="step-ca-inspector-client",
+    description="Step CA Inspector Client",
+    author="Benjamin Collet",
+    author_email="benjamin@collet.eu",
+    packages=find_packages(),
+    #long_description=open("README.md").read(),
+    #long_description_content_type="text/markdown",
+    install_requires=["requests>=2.20.0,<3.0", "PyYAML", "tabulate"],
+    keywords=["step-ca-inspector"],
+    version="0.0.1",
+    classifiers=[
+        "Intended Audience :: Developers",
+        "Development Status :: 3 - Alpha",
+        "Programming Language :: Python :: 3",
+    ],
+    entry_points={
+        "console_scripts": [
+            "step-ca-inspector = step_ca_inspector_client.cli:main",
+        ],
+    },
+)
diff --git a/step_ca_inspector_client/__init__.py b/step_ca_inspector_client/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/step-ca-inspector.py b/step_ca_inspector_client/cli.py
old mode 100755
new mode 100644
similarity index 64%
rename from step-ca-inspector.py
rename to step_ca_inspector_client/cli.py
index 529347a..700c753
--- a/step-ca-inspector.py
+++ b/step_ca_inspector_client/cli.py
@@ -5,7 +5,7 @@ import requests
 from urllib.parse import urljoin
 from datetime import datetime, timedelta, timezone
 from tabulate import tabulate
-from config import config
+from step_ca_inspector_client.config import config
 
 config()
 
@@ -126,7 +126,7 @@ def get_ssh_cert(serial):
         )
 
     cert_tbl.append(["Extensions", "\n".join(cert["extensions"])])
-    #cert_tbl.append(["Signing key", cert["signing_key"]])
+    # cert_tbl.append(["Signing key", cert["signing_key"]])
     cert_tbl.append(["Status", cert["status"]])
 
     print(tabulate(cert_tbl, tablefmt="fancy_grid"))
@@ -265,125 +265,138 @@ def dump_x509_cert(serial, cert_format="pem"):
     print(cert["pem"].rstrip())
 
 
-parser = argparse.ArgumentParser(description="Step CA Inspector")
-subparsers = parser.add_subparsers(
-    help="Object to inspect", dest="object", required=True
-)
-x509_parser = subparsers.add_parser("x509", help="x509 certificates")
-x509_subparsers = x509_parser.add_subparsers(
-    help="Action for perform", dest="action", required=True
-)
-x509_list_parser = x509_subparsers.add_parser("list", help="List x509 certificates")
-x509_list_parser.add_argument(
-    "--show-expired",
-    "-e",
-    action="store_true",
-    default=False,
-    help="Show expired certificates",
-)
-x509_list_parser.add_argument(
-    "--show-revoked",
-    "-r",
-    action="store_true",
-    default=False,
-    help="Show revoked certificates",
-)
-x509_list_parser.add_argument(
-    "--sort-by",
-    "-s",
-    type=str,
-    choices=["not_after", "not_before"],
-    default="not_after",
-    help="Sort certificates",
-)
-x509_details_parser = x509_subparsers.add_parser(
-    "details", help="Show an x509 certificate details"
-)
-x509_details_parser.add_argument(
-    "--serial", "-s", type=str, required=True, help="Certificate serial"
-)
-x509_details_parser.add_argument(
-    "--show-cert",
-    "-c",
-    action="store_true",
-    default=False,
-    help="Show certificate (PEM)",
-)
-x509_details_parser.add_argument(
-    "--show-pubkey",
-    "-p",
-    action="store_true",
-    default=False,
-    help="Show public key (PEM)",
-)
-x509_dump_parser = x509_subparsers.add_parser("dump", help="Dump an x509 certificate")
-x509_dump_parser.add_argument(
-    "--serial", "-s", type=str, required=True, help="Certificate serial"
-)
-x509_dump_parser.add_argument(
-    "--format",
-    "-f",
-    type=str,
-    choices=["pem"],
-    required=False,
-    help="Certificate format",
-)
-ssh_parser = subparsers.add_parser("ssh", help="ssh certificates")
-ssh_subparsers = ssh_parser.add_subparsers(
-    help="Action for perform", dest="action", required=True
-)
-ssh_list_parser = ssh_subparsers.add_parser("list", help="List ssh certificates")
-ssh_list_parser.add_argument(
-    "--show-expired",
-    "-e",
-    action="store_true",
-    default=False,
-    help="Show expired certificates",
-)
-ssh_list_parser.add_argument(
-    "--show-revoked",
-    "-r",
-    action="store_true",
-    default=False,
-    help="Show revoked certificates",
-)
-ssh_list_parser.add_argument(
-    "--sort-by",
-    "-s",
-    type=str,
-    choices=["not_after", "not_before"],
-    default="not_after",
-    help="Sort certificates (default: not_after)",
-)
-ssh_details_parser = ssh_subparsers.add_parser(
-    "details", help="Show an ssh certificate details"
-)
-ssh_details_parser.add_argument(
-    "--serial", "-s", type=str, required=True, help="Certificate serial"
-)
-ssh_dump_parser = ssh_subparsers.add_parser("dump", help="Dump an ssh certificate")
-ssh_dump_parser.add_argument(
-    "--serial", "-s", type=str, required=True, help="Certificate serial"
-)
-args = parser.parse_args()
+def main():
+    parser = argparse.ArgumentParser(description="Step CA Inspector")
+    subparsers = parser.add_subparsers(
+        help="Object to inspect", dest="object", required=True
+    )
+    x509_parser = subparsers.add_parser("x509", help="x509 certificates")
+    x509_subparsers = x509_parser.add_subparsers(
+        help="Action for perform", dest="action", required=True
+    )
+    x509_list_parser = x509_subparsers.add_parser("list", help="List x509 certificates")
+    x509_list_parser.add_argument(
+        "--show-expired",
+        "-e",
+        action="store_true",
+        default=False,
+        help="Show expired certificates",
+    )
+    x509_list_parser.add_argument(
+        "--show-revoked",
+        "-r",
+        action="store_true",
+        default=False,
+        help="Show revoked certificates",
+    )
+    x509_list_parser.add_argument(
+        "--sort-by",
+        "-s",
+        type=str,
+        choices=["not_after", "not_before"],
+        default="not_after",
+        help="Sort certificates",
+    )
+    x509_details_parser = x509_subparsers.add_parser(
+        "details", help="Show an x509 certificate details"
+    )
+    x509_details_parser.add_argument(
+        "--serial", "-s", type=str, required=True, help="Certificate serial"
+    )
+    x509_details_parser.add_argument(
+        "--show-cert",
+        "-c",
+        action="store_true",
+        default=False,
+        help="Show certificate (PEM)",
+    )
+    x509_details_parser.add_argument(
+        "--show-pubkey",
+        "-p",
+        action="store_true",
+        default=False,
+        help="Show public key (PEM)",
+    )
+    x509_dump_parser = x509_subparsers.add_parser(
+        "dump", help="Dump an x509 certificate"
+    )
+    x509_dump_parser.add_argument(
+        "--serial", "-s", type=str, required=True, help="Certificate serial"
+    )
+    x509_dump_parser.add_argument(
+        "--format",
+        "-f",
+        type=str,
+        choices=["pem"],
+        required=False,
+        help="Certificate format",
+    )
+    ssh_parser = subparsers.add_parser("ssh", help="ssh certificates")
+    ssh_subparsers = ssh_parser.add_subparsers(
+        help="Action for perform", dest="action", required=True
+    )
+    ssh_list_parser = ssh_subparsers.add_parser("list", help="List ssh certificates")
+    ssh_list_parser.add_argument(
+        "--show-expired",
+        "-e",
+        action="store_true",
+        default=False,
+        help="Show expired certificates",
+    )
+    ssh_list_parser.add_argument(
+        "--show-revoked",
+        "-r",
+        action="store_true",
+        default=False,
+        help="Show revoked certificates",
+    )
+    ssh_list_parser.add_argument(
+        "--sort-by",
+        "-s",
+        type=str,
+        choices=["not_after", "not_before"],
+        default="not_after",
+        help="Sort certificates (default: not_after)",
+    )
+    ssh_details_parser = ssh_subparsers.add_parser(
+        "details", help="Show an ssh certificate details"
+    )
+    ssh_details_parser.add_argument(
+        "--serial", "-s", type=str, required=True, help="Certificate serial"
+    )
+    ssh_dump_parser = ssh_subparsers.add_parser("dump", help="Dump an ssh certificate")
+    ssh_dump_parser.add_argument(
+        "--serial", "-s", type=str, required=True, help="Certificate serial"
+    )
+    args = parser.parse_args()
 
-if args.object == "x509":
-    if args.action == "list":
-        list_x509_certs(
-            revoked=args.show_revoked, expired=args.show_expired, sort_key=args.sort_by
-        )
-    elif args.action == "details":
-        get_x509_cert(
-            serial=args.serial, show_cert=args.show_cert, show_pubkey=args.show_pubkey
-        )
-    elif args.action == "dump":
-        dump_x509_cert(serial=args.serial)
-elif args.object == "ssh":
-    if args.action == "list":
-        list_ssh_certs(
-            revoked=args.show_revoked, expired=args.show_expired, sort_key=args.sort_by
-        )
-    elif args.action == "details":
-        get_ssh_cert(serial=args.serial)
-    elif args.action == "dump":
-        dump_ssh_cert(serial=args.serial)
+    if args.object == "x509":
+        if args.action == "list":
+            list_x509_certs(
+                revoked=args.show_revoked,
+                expired=args.show_expired,
+                sort_key=args.sort_by,
+            )
+        elif args.action == "details":
+            get_x509_cert(
+                serial=args.serial,
+                show_cert=args.show_cert,
+                show_pubkey=args.show_pubkey,
+            )
+        elif args.action == "dump":
+            dump_x509_cert(serial=args.serial)
+    elif args.object == "ssh":
+        if args.action == "list":
+            list_ssh_certs(
+                revoked=args.show_revoked,
+                expired=args.show_expired,
+                sort_key=args.sort_by,
+            )
+        elif args.action == "details":
+            get_ssh_cert(serial=args.serial)
+        elif args.action == "dump":
+            dump_ssh_cert(serial=args.serial)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/config.py b/step_ca_inspector_client/config.py
similarity index 100%
rename from config.py
rename to step_ca_inspector_client/config.py