diff --git a/qim3d/gui/annotation_tool.py b/qim3d/gui/annotation_tool.py
index cdd29f5599bcfff96acb5bd506a9212107b03b40..c3c60c1dc1dfe23d68c0e16c31e692859446967c 100644
--- a/qim3d/gui/annotation_tool.py
+++ b/qim3d/gui/annotation_tool.py
@@ -353,7 +353,10 @@ class Operations:
         ] + output_masks_update
 
 
+def run_interface(host = "0.0.0.0"):
+    gradio_interface = Interface().create_interface()
+    internal_tools.run_gradio_app(gradio_interface,host)
+
 if __name__ == "__main__":
     # Creates interface
-    gradio_interface = Interface().create_interface()
-    internal_tools.run_gradio_app(gradio_interface)
+    run_interface()
\ No newline at end of file
diff --git a/qim3d/gui/data_explorer.py b/qim3d/gui/data_explorer.py
index 17eb8268e5db8275e64cabb19a1b01519c9d3e04..1be62208c2d8007872ed2e1b961b3474da956020 100644
--- a/qim3d/gui/data_explorer.py
+++ b/qim3d/gui/data_explorer.py
@@ -629,8 +629,11 @@ class Pipeline:
 
         return vol_hist, bin_edges
 
+def run_interface(host = "0.0.0.0"):
+    gradio_interface = Interface().create_interface()
+    internal_tools.run_gradio_app(gradio_interface,host)
+
 
 if __name__ == "__main__":
     # Creates interface
-    gradio_interface = Interface().create_interface()
-    internal_tools.run_gradio_app(gradio_interface)
+    run_interface()
\ No newline at end of file
diff --git a/qim3d/gui/iso3d.py b/qim3d/gui/iso3d.py
index a60b761ed53e915ed18a7d8f71b67fc9abe6ebb9..1536aa7d4854ac463326295f396c914ac72b137e 100644
--- a/qim3d/gui/iso3d.py
+++ b/qim3d/gui/iso3d.py
@@ -397,7 +397,11 @@ class Interface:
         )
 
 
+def run_interface(host = "0.0.0.0"):
+    gradio_interface = Interface().create_interface()
+    internal_tools.run_gradio_app(gradio_interface,host)
+
+
 if __name__ == "__main__":
     # Creates interface
-    gradio_interface = Interface().create_interface()
-    internal_tools.run_gradio_app(gradio_interface)
+    run_interface()
\ No newline at end of file
diff --git a/qim3d/gui/local_thickness.py b/qim3d/gui/local_thickness.py
index 1e179eed1effbc60d071237e75e279dab3027965..b3a7dce18fb44beb6a2e7c543295bcdc822f760d 100644
--- a/qim3d/gui/local_thickness.py
+++ b/qim3d/gui/local_thickness.py
@@ -421,8 +421,10 @@ class Pipeline:
 
         return filename
 
+def run_interface(host = "0.0.0.0"):
+    gradio_interface = Interface().create_interface()
+    internal_tools.run_gradio_app(gradio_interface,host)
 
 if __name__ == "__main__":
     # Creates interface
-    gradio_interface = Interface().create_interface()
-    internal_tools.run_gradio_app(gradio_interface)
+    run_interface()
\ No newline at end of file
diff --git a/qim3d/utils/cli.py b/qim3d/utils/cli.py
new file mode 100644
index 0000000000000000000000000000000000000000..f48a5b81c974fdcf73110b5f517a0f7c49d6c6d0
--- /dev/null
+++ b/qim3d/utils/cli.py
@@ -0,0 +1,35 @@
+import argparse
+from qim3d.gui import data_explorer, iso3d, annotation_tool, local_thickness
+
+def main():
+    parser = argparse.ArgumentParser(description='Qim3d command-line interface.')
+    subparsers = parser.add_subparsers(title='Subcommands', dest='subcommand')
+
+    # subcommands
+    gui_parser = subparsers.add_parser('gui', help = 'Graphical User Interfaces.')
+
+    gui_parser.add_argument('--data-explorer', action='store_true', help='Run data explorer.')
+    gui_parser.add_argument('--iso3d', action='store_true', help='Run iso3d.')
+    gui_parser.add_argument('--annotation-tool', action='store_true', help='Run annotation tool.')
+    gui_parser.add_argument('--local-thickness', action='store_true', help='Run local thickness tool.')
+    gui_parser.add_argument('--host', default='0.0.0.0', help='Desired host.')
+
+    args = parser.parse_args()
+
+    if args.subcommand == 'gui':
+        arghost = args.host
+        if args.data_explorer:
+            
+            data_explorer.run_interface(arghost)
+
+        elif args.iso3d:
+            iso3d.run_interface(arghost)
+        
+        elif args.annotation_tool:
+            annotation_tool.run_interface(arghost)
+        
+        elif args.local_thickness:
+            local_thickness.run_interface(arghost)
+
+if __name__ == '__main__':
+    main()
\ No newline at end of file
diff --git a/qim3d/utils/internal_tools.py b/qim3d/utils/internal_tools.py
index a4f6ede02c206a68e8039e7aed19ad20e478d9f5..465cd1cff51b86244813b2c02e2e80b5a142eed5 100644
--- a/qim3d/utils/internal_tools.py
+++ b/qim3d/utils/internal_tools.py
@@ -267,8 +267,8 @@ def get_port_dict():
 
     return port_dict
 
-def run_gradio_app(gradio_interface):
-    host = "0.0.0.0"
+def run_gradio_app(gradio_interface, host = "0.0.0.0"):
+
     # Get port using the QIM API
     port_dict = get_port_dict()
 
@@ -291,7 +291,7 @@ def run_gradio_app(gradio_interface):
     print(f"http://{host}:{port}{path}")
 
     # Run the FastAPI server usign uvicorn
-    run(app, host="0.0.0.0", port=int(port))
+    run(app, host=host, port=int(port))
 
 
 def get_css():
diff --git a/setup.py b/setup.py
index 899bafa6fd0d4810789eda3c9d369e7f617c496f..df3991077413fb8a556c94379258dfd6a6d96fcb 100644
--- a/setup.py
+++ b/setup.py
@@ -18,6 +18,11 @@ setup(
     url="https://lab.compute.dtu.dk/QIM/tools/qim3d",
     packages=find_packages(),
     include_package_data=True,
+    entry_points = {
+        'console_scripts': [
+            'qim3d=qim3d.utils.cli:main'
+        ]
+    },
     classifiers=[
         "License :: OSI Approved :: MIT License",
         "Programming Language :: Python :: 3",