diff --git a/python-libs/poulpe/cli.py b/python-libs/poulpe/cli.py
new file mode 100644
index 0000000000000000000000000000000000000000..d6071d0f7edb2ca21c96855076eda68b0b5be81f_cHl0aG9uLWxpYnMvcG91bHBlL2NsaS5weQ==
--- /dev/null
+++ b/python-libs/poulpe/cli.py
@@ -0,0 +1,29 @@
+from importlib import resources
+import subprocess
+
+import click
+
+
+@click.command(
+    no_args_is_help=True,
+    context_settings={
+        "ignore_unknown_options": True,
+        "allow_interspersed_args": False,
+    },
+)
+@click.argument('subcommand')
+@click.argument('subcommand_args', nargs=-1, type=click.UNPROCESSED)
+def exec_subcommand(subcommand, subcommand_args):
+    """Wrapper around Poulpe binaries for ease of calling"""
+    subcommand_file = resources.files("poulpe.bin").joinpath(subcommand)
+
+    if not subcommand_file.is_file():
+        raise click.BadParameter(f"Subcommand `{subcommand}` does not exist.")
+
+    with resources.as_file(subcommand_file) as f:
+        cmd = [str(f)] + list(subcommand_args)
+        exit(subprocess.call(cmd))
+
+
+if __name__ == '__main__':
+    exec_subcommand()
diff --git a/setup.cfg b/setup.cfg
index 560613c17607999a49682e5bdbb5125e3bbf0e4d_c2V0dXAuY2Zn..d6071d0f7edb2ca21c96855076eda68b0b5be81f_c2V0dXAuY2Zn 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,4 +2,12 @@
 name = poulpe
 version = 0.0.0
 
+[options]
+install_requires =
+    click == 8.1
+    importlib-resources
+    toml
+packages = find_namespace:
+package_dir =
+    = python-libs
 
@@ -5,7 +13,5 @@
 
-[options]
-packages=poulpe
-package_dir=
-    =python-libs
+[options.package_data]
+poulpe.bin = *
 
 [options.packages.find]
@@ -10,3 +16,7 @@
 
 [options.packages.find]
-where=python-libs
+where = python-libs
+
+[options.entry_points]
+console_scripts =
+    poulpe = poulpe.cli:exec_subcommand
\ No newline at end of file