diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/CMakeLists.txt b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/CMakeLists.txt
index be386caddae3b7b8750bbd161f5a91acaaeca540..9ef8aee98477e24cf11ef382991242ae1b1df330 100644
--- a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/CMakeLists.txt
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/CMakeLists.txt
@@ -9,5 +9,6 @@ atlas_add_component( DumpGeo
    LINK_LIBRARIES AthenaBaseComps CxxUtils GaudiKernel GeoExporter )
 
 # Install files from the package.
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py )
 atlas_install_scripts( share/dump-geo )
diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/DumpGeo/DumpGeo.h b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/DumpGeo/DumpGeo.h
index 594e87b863685db3c94b6c521feecb0ba2bf2ab0..7b0ceffebf6fcb192520d3a8fa9000dd83e885b0 100755
--- a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/DumpGeo/DumpGeo.h
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/DumpGeo/DumpGeo.h
@@ -42,7 +42,13 @@ class ATLAS_NOT_THREAD_SAFE DumpGeo: public AthAlgorithm,
   IToolSvc* m_toolSvc;
   GeoExporter* m_geoExporter;
 
-  bool m_noGui;//For testing job-options in RTT
+  // bool m_noGui;//For testing job-options in RTT
+
+// Properties
+  // -- Athena-related
+  Gaudi::Property<std::string> m_atlasRelease{this, "AtlasRelease", "", "The current, in use Atlas release"}; 
+
+
 };
 
 #endif
diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/python/DumpGeoConfig.py b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/python/DumpGeoConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..43bc9389211deab5a4c776cbee6eba392578f7b4
--- /dev/null
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/python/DumpGeoConfig.py
@@ -0,0 +1,194 @@
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+#from AthenaConfiguration.Enums import Format
+
+import os
+
+def configureGeometry(flags, cfg):
+    if flags.Detector.GeometryBpipe:
+        from BeamPipeGeoModel.BeamPipeGMConfig import BeamPipeGeometryCfg
+        cfg.merge(BeamPipeGeometryCfg(flags))
+
+    if flags.Detector.GeometryPixel:
+        from PixelGeoModel.PixelGeoModelConfig import PixelReadoutGeometryCfg
+        cfg.merge(PixelReadoutGeometryCfg(flags))
+
+    if flags.Detector.GeometrySCT:
+        from SCT_GeoModel.SCT_GeoModelConfig import SCT_ReadoutGeometryCfg
+        cfg.merge(SCT_ReadoutGeometryCfg(flags))
+
+    if flags.Detector.GeometryTRT:
+        from TRT_GeoModel.TRT_GeoModelConfig import TRT_ReadoutGeometryCfg
+        cfg.merge(TRT_ReadoutGeometryCfg(flags))
+
+    if flags.Detector.GeometryITkPixel:
+        from PixelGeoModelXml.ITkPixelGeoModelConfig import ITkPixelReadoutGeometryCfg
+        cfg.merge(ITkPixelReadoutGeometryCfg(flags))
+
+    if flags.Detector.GeometryITkStrip:
+        from StripGeoModelXml.ITkStripGeoModelConfig import ITkStripReadoutGeometryCfg
+        cfg.merge(ITkStripReadoutGeometryCfg(flags))
+
+    if flags.Detector.GeometryLAr:
+        from LArGeoAlgsNV.LArGMConfig import LArGMCfg
+        cfg.merge(LArGMCfg(flags))
+
+    if flags.Detector.GeometryTile:
+        from TileGeoModel.TileGMConfig import TileGMCfg
+        cfg.merge(TileGMCfg(flags))
+
+    if flags.Detector.GeometryMuon:
+        from MuonConfig.MuonGeometryConfig import MuonGeoModelCfg
+        cfg.merge(MuonGeoModelCfg(flags))
+
+def getATLASVersion():
+    import os
+
+    if "AtlasVersion" in os.environ:
+        return os.environ["AtlasVersion"]
+    if "AtlasBaseVersion" in os.environ:
+        return os.environ["AtlasBaseVersion"]
+    return "Unknown"
+
+def DumpGeoCfg(flags, name="DumpGeoCA", **kwargs):
+    # This is based on a few old-style configuation files:
+    # JiveXML_RecEx_config.py
+    # JiveXML_jobOptionBase.py
+    result = ComponentAccumulator()
+
+    #print(dir("args: ", args)) # debug
+
+    # set Alg's properties
+    kwargs.setdefault("AtlasRelease", getATLASVersion())
+
+    # TODO: Fix this
+    # This is a temporary hack to reflect how detdescr is handled in the old bash-driven DumpGeo
+    # This should be replaced by proper python flags and Gaudy properties
+    os.environ["DUMPGEODETDESCRTAG"] = args.detdescr # save to an env var, for later use in GeoModelStandalone/GeoExporter
+    if args.force == True:
+        os.environ["DUMPGEOOVERWRITE"] = "1" # save to an env var, for later use in GeoModelStandalone/GeoExporter
+
+    the_alg = CompFactory.DumpGeo(name="DumpGeoAlg", **kwargs)
+    result.addEventAlgo(the_alg, primary=True)
+    return result
+
+
+if __name__=="__main__":
+    # Run with e.g. python -m DumpGeo.DumpGeoConfig --detdescr=<ATLAS-geometry-tag> --filter=[<list of tree tops>]
+    
+    # from AthenaConfiguration.Enums import Format
+    from AthenaCommon.Logging import logging
+    from AthenaCommon.Constants import VERBOSE
+
+    # ++++ Firstly we setup flags ++++
+    _logger = logging.getLogger('DumpGeo')
+    _logger.setLevel(VERBOSE)
+
+    from AthenaConfiguration.AllConfigFlags import initConfigFlags
+    flags = initConfigFlags()
+    flags.Concurrency.NumThreads = 0 
+    # ^ VP1 will not work with the scheduler, since its condition/data dependencies are not known in advance
+    # More in details: the scheduler needs to know BEFORE the event, what the dependencies of each Alg are. 
+    # So for VP1, no dependencies are declared, which means the conditions data is not there. 
+    # So when I load tracks, the geometry is missing and it crashes. 
+    # Turning off the scheduler (with NumThreads=0) fixes this.
+
+    parser = flags.getArgumentParser()
+    parser.prog = 'dump-geo'
+    # here we extend the parser
+    # Add DumpGeo-specific arguments here, but remember you can also directly pass flags in form <flagName>=<value>.
+    # e.g.
+    # parser.add_argument("-o", "--output", dest="output", default='Event.json',
+    #                     help="write JSON to FILE", metavar="FILE")
+    parser.add_argument("--detdescr", default='',
+                        help="The ATLAS geometry tag you want to dump", metavar="DETDESCR")
+    parser.add_argument("-f", "--force",
+                        help="Force to override an existing SQLite output file with the same name, if any", action = 'store_true')
+
+    args = flags.fillFromArgs(parser=parser)
+
+    if 'help' in args:
+        # No point doing more here, since we just want to print the help.
+        import sys
+        sys.exit()
+
+    _logger.verbose("+ About to set flags related to the input")
+
+    # Empty input is not normal for Athena, so we will need to check 
+    # this repeatedly below
+    vp1_empty_input = False  
+    # This covers the use case where we launch VP1
+    # without input files; e.g., to check the detector description
+    if (flags.Input.Files == [] or 
+        flags.Input.Files == ['_ATHENA_GENERIC_INPUTFILE_NAME_']):
+        from Campaigns.Utils import Campaign
+        from AthenaConfiguration.TestDefaults import defaultGeometryTags
+
+        vp1_empty_input = True
+        # NB Must set e.g. ConfigFlags.Input.Runparse_args() Number and
+        # ConfigFlags.Input.TimeStamp before calling the 
+        # MainServicesCfg to avoid it attempting auto-configuration 
+        # from an input file, which is empty in this use case.
+        # If you don't have it, it (and/or other Cfg routines) complains and crashes. 
+        # See also: 
+        # https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/python/SCT_DCSConditionsTestAlgConfig.py#0023
+        flags.Input.ProjectName = "mc20_13TeV"
+        flags.Input.RunNumbers = [330000]  
+        flags.Input.TimeStamps = [1]  
+        flags.Input.TypedCollections = []
+
+        # set default CondDB and Geometry version
+        flags.IOVDb.GlobalTag = "OFLCOND-MC23-SDR-RUN3-02"
+        flags.Input.isMC = True
+        flags.Input.MCCampaign = Campaign.Unknown
+        flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN3
+    _logger.verbose("+ ... Done")
+    _logger.verbose("+ empty input: '%s'" % vp1_empty_input)
+
+    _logger.verbose("+ detdescr flag: '%s'" % args.detdescr)
+
+
+    _logger.verbose("+ About to set the detector flags")
+    # So we can now set up the geometry flags from the input
+    from AthenaConfiguration.DetectorConfigFlags import setupDetectorFlags
+    setupDetectorFlags(flags, None, use_metadata=not vp1_empty_input,
+                       toggle_geometry=True, keep_beampipe=True)
+    _logger.verbose("+ ... Done")
+
+    if args.detdescr:
+        _logger.verbose("+ About to set a custom detector description tag")
+        flags.GeoModel.AtlasVersion = args.detdescr
+        _logger.verbose("+ ... Done")
+
+
+    # finalize setting flags: lock them.
+    flags.lock()
+
+    # DEBUG -- inspect the flags
+    # flags.dump()
+    # flags._loadDynaFlags('GeoModel')
+    # flags._loadDynaFlags('Detector')
+    # flags.dump('Detector.(Geometry|Enable)', True)
+
+    # ++++ Now we setup the actual configuration ++++
+
+    # NB Must have set ConfigFlags.Input.RunNumber and
+    # ConfigFlags.Input.TimeStamp before calling to avoid
+    # attempted auto-configuration from an input file.
+    _logger.verbose("+ Setup main services, and input file reading")
+
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+    cfg = MainServicesCfg(flags)
+  
+    _logger.verbose("+ ...Done")
+
+    _logger.verbose("+ About to setup geometry")
+    configureGeometry(flags,cfg)
+    _logger.verbose("+ ...Done")
+
+    # configure VP1
+    cfg.merge(DumpGeoCfg(flags, args)) 
+    cfg.run()
+
diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/share/dump-geo.py b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/share/dump-geo.py
index 1a64d2a46e032877b819e0a1111c1cf63ad52fea..cfce17503f7f4c6dc82ab4a1dee8adf7c1aba93c 100644
--- a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/share/dump-geo.py
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/share/dump-geo.py
@@ -161,7 +161,8 @@ topSequence = AlgSequence()
 
 #Detector setup:
 from AthenaCommon.DetFlags import DetFlags
-if (vp1ID): DetFlags.ID_setOn()
+if (vp1ID): 
+  DetFlags.ID_setOn()
 else:       DetFlags.ID_setOff()
 if (vp1Calo): DetFlags.Calo_setOn()
 else:         DetFlags.Calo_setOff()
diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/src/DumpGeo.cxx b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/src/DumpGeo.cxx
index 4312c8ab2890b309242272c29248be8a7c1d0116..57c6a4fb53c5a1e5cf042ef962f6d0723738b83b 100755
--- a/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/src/DumpGeo.cxx
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/DumpGeo/src/DumpGeo.cxx
@@ -17,7 +17,7 @@ DumpGeo::DumpGeo(const std::string& name, ISvcLocator* svcLocator):
   AthAlgorithm(name, svcLocator),
   m_toolSvc(0),m_geoExporter(0)
 {
-  declareProperty("NoGui",m_noGui=false);
+  // declareProperty("NoGui",m_noGui=false);
 
   ::setenv("LCGPATCH_COINMULTISELECT","1",1);
 }
diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx b/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
index c9ff24478411b42e32221827cad289a9d078a6a1..1ab3f7b72c756bf4dd3b7e24f307bbeb5c8440d2 100755
--- a/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
+++ b/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
@@ -135,6 +135,8 @@ void GeoExporter::init()
   else {
     VP1Msg::message("User's settings - DetDescrTag: " + user_detdescrtag);
     }
+  // -- get 'force' option
+  bool forceOverride = environment.value("DUMPGEOFORCEOVERRIDE");
   // -- get sub-systems settings
   bool user_noid = environment.value("DUMPGEO_NOID").toInt();
   bool user_nocalo = environment.value("DUMPGEO_NOCALO").toInt();